Repository: denoland/deno
File: resolvers/node/resolution.rs (Rust)

Code before:
use crate::errors::ResolvePkgJsonBinExportError;
use crate::errors::TypesNotFoundError;
use crate::errors::TypesNotFoundErrorData;
use crate::errors::UnsupportedDirImportError;
use crate::errors::UnsupportedEsmUrlSchemeError;
use crate::npm::InNpmPackageCheckerRc;
#[allow(clippy::disallowed_types)]
use crate::sync::MaybeArc;
use crate::NpmPackageFolderResolverRc;
use crate::PackageJsonResolverRc;
use crate::PathClean;

pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"];
static TYPES_ONLY_CONDITIONS: &[&str] = &["types"];

pub fn deno_conditions_from_resolution_mode(
  resolution_mode: ResolutionMode,
) -> &'static [&'static str] {
  match resolution_mode {
    ResolutionMode::Import => DEFAULT_CONDITIONS,
    ResolutionMode::Require => REQUIRE_CONDITIONS,
  }
}

pub struct ConditionsFromResolutionMode {
  #[allow(clippy::disallowed_types)]
  pub func: MaybeArc<
    dyn Fn(ResolutionMode) -> &'static [&'static str] + Send + Sync + 'static,
  >,
}

impl Debug for ConditionsFromResolutionMode {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.debug_struct("ConditionsFromResolutionMode").finish()
  }
}

impl ConditionsFromResolutionMode {
  pub fn new(
    func: impl Fn(ResolutionMode) -> &'static [&'static str] + Send + Sync + 'static,
  ) -> Self {
    Self {
      #[allow(clippy::disallowed_types)]
      func: MaybeArc::new(func),
    }
  }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ResolutionMode {

Review comment (suggestion):
Maybe this should just be: `pub struct ConditionsFromResolutionMode(Option<Box<dyn Fn(ResolutionMode) -> &'static [&'static str]>>)` with a default implementation of `ConditionsFromResolutionMode(None)` that will instead use `deno_conditions_from_resolution_mode`? That way the other code can just do `ConditionsFromResolutionMode::default()` instead of needing to know about `deno_conditions_from_resolution_mode`

Code after:
use crate::errors::ResolvePkgJsonBinExportError;
use crate::errors::TypesNotFoundError;
use crate::errors::TypesNotFoundErrorData;
use crate::errors::UnsupportedDirImportError;
use crate::errors::UnsupportedEsmUrlSchemeError;
use crate::npm::InNpmPackageCheckerRc;
use crate::NpmPackageFolderResolverRc;
use crate::PackageJsonResolverRc;
use crate::PathClean;

pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"];
static TYPES_ONLY_CONDITIONS: &[&str] = &["types"];

type ConditionsFromResolutionModeFn = Box<
  dyn Fn(ResolutionMode) -> &'static [&'static str] + Send + Sync + 'static,
>;

#[derive(Default)]
pub struct ConditionsFromResolutionMode(Option<ConditionsFromResolutionModeFn>);

impl Debug for ConditionsFromResolutionMode {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    f.debug_struct("ConditionsFromResolutionMode").finish()
  }
}

impl ConditionsFromResolutionMode {
  pub fn new(func: ConditionsFromResolutionModeFn) -> Self {
    Self(Some(func))
  }

  fn resolve(
    &self,
    resolution_mode: ResolutionMode,
  ) -> &'static [&'static str] {
    match &self.0 {
      Some(func) => func(ResolutionMode::Import),
      None => resolution_mode.default_conditions(),
    }
  }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ResolutionMode {
  Import,
  Require,
}

impl ResolutionMode {
  pub fn default_conditions(&self) -> &'static [&'static str] {