use compact_str::CompactString;
use crate::imports::{ImportKind, RawImport};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Resolved {
Path(CompactString),
External(CompactString),
Unresolved(UnresolvedReason),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum UnresolvedReason {
NotFound,
Unsupported,
Failed {
kind: FailedKind,
detail: CompactString,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FailedKind {
Config,
Io,
InvalidSpecifier,
Other,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResolutionCompleteness {
Complete,
Partial,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResolutionOutcome {
pub resolved: Resolved,
pub dependencies: Vec<CompactString>,
pub notes: Vec<CompactString>,
pub completeness: ResolutionCompleteness,
}
pub trait Resolve: Send + Sync {
fn baseline_completeness(&self) -> ResolutionCompleteness {
ResolutionCompleteness::Complete
}
fn resolve(&self, from_file: &str, import: &RawImport) -> ResolutionOutcome;
fn clear_cache(&self);
}
#[derive(Default)]
pub struct ResolverSet {
pub js: Option<Box<dyn Resolve>>,
pub rust: Option<Box<dyn Resolve>>,
}
impl ResolverSet {
#[must_use]
pub fn baseline_completeness(&self, language: &str) -> ResolutionCompleteness {
let resolver = match language {
"rust" => self.rust.as_deref(),
"typescript" | "tsx" | "javascript" | "jsx" | "vue" => self.js.as_deref(),
_ => None,
};
resolver.map_or(
ResolutionCompleteness::Complete,
Resolve::baseline_completeness,
)
}
pub fn resolve(&self, from_file: &str, import: &RawImport) -> ResolutionOutcome {
let resolver = match import.kind {
ImportKind::RustUse | ImportKind::RustMod => self.rust.as_deref(),
_ => self.js.as_deref(),
};
resolver.map_or_else(unsupported, |resolver| resolver.resolve(from_file, import))
}
pub fn clear_cache(&self) {
if let Some(resolver) = &self.js {
resolver.clear_cache();
}
if let Some(resolver) = &self.rust {
resolver.clear_cache();
}
}
}
fn unsupported() -> ResolutionOutcome {
ResolutionOutcome {
resolved: Resolved::Unresolved(UnresolvedReason::Unsupported),
dependencies: Vec::new(),
notes: Vec::new(),
completeness: ResolutionCompleteness::Complete,
}
}
#[cfg(feature = "resolve-js")]
pub mod js;
#[cfg(feature = "resolve-rust")]
pub mod rust;