diff --git a/src/searcher.rs b/src/searcher.rs index 673e99b..8281306 100644 --- a/src/searcher.rs +++ b/src/searcher.rs @@ -40,12 +40,46 @@ impl UserData for Searcher { } } +/// Like `Searcher`, but with `modules` values encoded as `&'static str` +/// to facilitate compile-time includes of Fennel source code. +struct StaticSearcher { + modules: HashMap, + globals: RegistryKey, +} + +impl StaticSearcher { + fn new(modules: HashMap, globals: RegistryKey) -> Self { + Self { modules, globals } + } +} + +impl UserData for StaticSearcher { + fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Call, |lua_ctx, this, name: String| { + match this.modules.get(&name) { + Some(content) => Ok(Value::Function( + lua_ctx + .load(content) + .set_name(&name)? + .set_environment(lua_ctx.registry_value::(&this.globals)?)? + .into_function()?, + )), + None => Ok(Value::Nil), + } + }); + } +} + /// Extend `rlua::Context` to support `require`ing Lua modules by name. pub trait AddSearcher { /// Add a `HashMap` of Lua modules indexed by module name to Lua’s /// `package.searchers` table in an `rlua::Context`, with lookup /// functionality provided by the `rlua_searcher::Searcher` struct. fn add_searcher(&self, modules: HashMap) -> Result<()>; + + /// Like `add_searcher`, but with Fennel source code encoded as + /// `&'static str` to facilitate compile-time includes. + fn add_static_searcher(&self, modules: HashMap) -> Result<()>; } impl<'a> AddSearcher for Context<'a> { @@ -58,4 +92,14 @@ impl<'a> AddSearcher for Context<'a> { .set(searchers.len()? + 1, searcher) .map_err(|e| e.into()) } + + fn add_static_searcher(&self, modules: HashMap) -> Result<()> { + let globals = self.globals(); + let searchers: Table = globals.get::<_, Table>("package")?.get("searchers")?; + let registry_key = self.create_registry_value(globals)?; + let searcher = StaticSearcher::new(modules, registry_key); + searchers + .set(searchers.len()? + 1, searcher) + .map_err(|e| e.into()) + } } diff --git a/tests/tests.rs b/tests/tests.rs index c143229..2e5586d 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -3,7 +3,7 @@ use rlua_searcher::{AddSearcher, Result}; use std::collections::HashMap; #[test] -fn it_works() { +fn add_searcher_works() { let lume = read_lume_to_string(); let name = "lume".to_string(); let mut map = HashMap::new(); @@ -21,6 +21,29 @@ fn it_works() { assert_eq!("hello lume", hello); } +#[test] +fn add_static_searcher_works() { + let lume = read_lume_to_str(); + let name = "lume".to_string(); + let mut map = HashMap::new(); + map.insert(name, lume); + + let lua = Lua::new(); + + let hello = lua + .context::<_, Result>(|lua_ctx| { + lua_ctx.add_static_searcher(map)?; + Ok(lua_ctx.load(r#"return require("lume")"#).eval()?) + }) + .unwrap(); + + assert_eq!("hello lume", hello); +} + fn read_lume_to_string() -> String { r#"return "hello lume""#.to_string() } + +fn read_lume_to_str() -> &'static str { + r#"return "hello lume""# +}