rquickjs_core/loader/
builtin_resolver.rs

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