diff --git a/src/searcher.rs b/src/searcher.rs
index 6181d44..3363a8a 100644
--- a/src/searcher.rs
+++ b/src/searcher.rs
@@ -3,7 +3,7 @@ use rlua::{Context, MetaMethod, RegistryKey, Table, UserData, UserDataMethods, V
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
-use std::path::Path;
+use std::path::{Path, PathBuf};
use crate::types::Result;
use crate::utils;
@@ -72,26 +72,40 @@ impl UserData for StaticSearcher {
}
}
-/// Like `Searcher`, but with `modules` values given as paths to files containing Lua
-/// source code to facilitate module reloading.
-struct PathSearcher
+/// Like `Searcher`, but with `modules` values given as paths to files the content of
+/// which can be read as Lua source code.
+///
+/// Facilitates Lua module reloading, and module reloading of any other programming
+/// language whose source code can be compiled to Lua.
+struct PolySearcher
where
P: 'static + AsRef + Send,
{
modules: HashMap,
globals: RegistryKey,
+
+ /// Function to read file content as Lua source code.
+ convert: Box rlua::Result + Send>,
}
-impl PathSearcher
+impl
PolySearcher
where
P: 'static + AsRef + Send,
{
- fn new(modules: HashMap, globals: RegistryKey) -> Self {
- Self { modules, globals }
+ fn new(
+ modules: HashMap,
+ globals: RegistryKey,
+ convert: Box rlua::Result + Send>,
+ ) -> Self {
+ Self {
+ modules,
+ globals,
+ convert,
+ }
}
}
-impl UserData for PathSearcher
+impl
UserData for PolySearcher
where
P: 'static + AsRef + Send,
{
@@ -108,11 +122,7 @@ where
path.to_path_buf()
};
- let mut content = String::new();
- let mut file = File::open(path)
- .map_err(|e| LuaError::RuntimeError(format!("io error: {:#?}", e)))?;
- file.read_to_string(&mut content)
- .map_err(|e| LuaError::RuntimeError(format!("io error: {:#?}", e)))?;
+ let content = (this.convert)(path)?;
Ok(Value::Function(
lua_ctx
@@ -144,6 +154,16 @@ pub trait AddSearcher {
fn add_path_searcher(&self, modules: HashMap) -> Result<()>
where
P: 'static + AsRef + Send;
+
+ /// Like `add_path_searcher`, but with user-provided closure for converting source
+ /// code to Lua.
+ fn add_poly_searcher(
+ &self,
+ modules: HashMap,
+ convert: Box rlua::Result + Send>,
+ ) -> Result<()>
+ where
+ P: 'static + AsRef + Send;
}
impl<'a> AddSearcher for Context<'a> {
@@ -168,13 +188,32 @@ impl<'a> AddSearcher for Context<'a> {
}
fn add_path_searcher(&self, modules: HashMap) -> Result<()>
+ where
+ P: 'static + AsRef + Send,
+ {
+ let convert = Box::new(|path| {
+ let mut content = String::new();
+ let mut file = File::open(path)
+ .map_err(|e| LuaError::RuntimeError(format!("io error: {:#?}", e)))?;
+ file.read_to_string(&mut content)
+ .map_err(|e| LuaError::RuntimeError(format!("io error: {:#?}", e)))?;
+ Ok(content)
+ });
+ self.add_poly_searcher(modules, convert)
+ }
+
+ fn add_poly_searcher(
+ &self,
+ modules: HashMap,
+ convert: Box rlua::Result + Send>,
+ ) -> Result<()>
where
P: 'static + AsRef + Send,
{
let globals = self.globals();
let searchers: Table = globals.get::<_, Table>("package")?.get("searchers")?;
let registry_key = self.create_registry_value(globals)?;
- let searcher = PathSearcher::new(modules, registry_key);
+ let searcher = PolySearcher::new(modules, registry_key, convert);
searchers
.set(searchers.len()? + 1, searcher)
.map_err(|e| e.into())