Skip to main content

rquickjs_core/loader/
builtin_resolver.rs

1use crate::{
2    loader::{ImportAttributes, Resolver},
3    Ctx, Error, Result,
4};
5use alloc::string::{String, ToString as _};
6#[cfg(not(feature = "std"))]
7use hashbrown::HashSet;
8use relative_path::RelativePath;
9#[cfg(feature = "std")]
10use std::collections::HashSet;
11
12/// The builtin module resolver
13///
14/// This resolver can also be used as the nested backing resolver in user-defined resolvers.
15#[derive(Debug, Default)]
16pub struct BuiltinResolver {
17    modules: HashSet<String>,
18}
19
20impl BuiltinResolver {
21    /// Add builtin module
22    pub fn add_module<P: Into<String>>(&mut self, path: P) -> &mut Self {
23        self.modules.insert(path.into());
24        self
25    }
26
27    /// Add builtin module
28    #[must_use]
29    pub fn with_module<P: Into<String>>(mut self, path: P) -> Self {
30        self.add_module(path);
31        self
32    }
33}
34
35impl Resolver for BuiltinResolver {
36    fn resolve<'js>(
37        &mut self,
38        _ctx: &Ctx<'js>,
39        base: &str,
40        name: &str,
41        _attributes: Option<ImportAttributes<'js>>,
42    ) -> Result<String> {
43        let full = if !name.starts_with('.') {
44            name.to_string()
45        } else {
46            let base = RelativePath::new(base);
47            if let Some(dir) = base.parent() {
48                dir.join_normalized(name).to_string()
49            } else {
50                name.to_string()
51            }
52        };
53
54        if self.modules.contains(&full) {
55            Ok(full)
56        } else {
57            Err(Error::new_resolving(base, name))
58        }
59    }
60}