make initial implementation
credit - https://github.com/AlphaModder/include-lua
This commit is contained in:
parent
187c5f55ea
commit
38c15af4dc
20
README.md
20
README.md
@ -11,20 +11,24 @@ and `require` the module.
|
|||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rlua_searcher::AddSearcher;
|
use rlua::Lua;
|
||||||
|
use rlua_searcher::{AddSearcher, Result};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let lume = read_lume_to_string();
|
let lume = read_lume_to_string();
|
||||||
let name = "lume";
|
let name = "lume".to_string();
|
||||||
let map = HashMap::new<String, String>();
|
let mut map = HashMap::new();
|
||||||
map.insert(name, lume);
|
map.insert(name, lume);
|
||||||
|
|
||||||
let lua = Lua::new;
|
let lua = Lua::new();
|
||||||
|
|
||||||
let hello = lua.context::<_, rlua::Result<_>>(|lua_ctx| {
|
let hello = lua
|
||||||
lua_ctx.add_searcher(map)?;
|
.context::<_, Result<String>>(|lua_ctx| {
|
||||||
Ok(lua_ctx.load(r#"require("lume")"#).eval()?)
|
lua_ctx.add_searcher(map)?;
|
||||||
}).unwrap();
|
Ok(lua_ctx.load(r#"return require("lume")"#).eval()?)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// prints "hello lume"
|
// prints "hello lume"
|
||||||
println!("{}", hello);
|
println!("{}", hello);
|
||||||
|
21
src/error.rs
Normal file
21
src/error.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
RLua(rlua::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<rlua::Error> for Error {
|
||||||
|
fn from(error: rlua::Error) -> Self {
|
||||||
|
Error::RLua(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let res = match self {
|
||||||
|
Error::RLua(e) => format!("rlua error:\n{:#?}", e),
|
||||||
|
};
|
||||||
|
write!(f, "{}", res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {}
|
14
src/lib.rs
14
src/lib.rs
@ -1,7 +1,7 @@
|
|||||||
#[cfg(test)]
|
mod searcher;
|
||||||
mod tests {
|
mod error;
|
||||||
#[test]
|
mod types;
|
||||||
fn it_works() {
|
|
||||||
assert_eq!(2 + 2, 4);
|
pub use crate::error::Error;
|
||||||
}
|
pub use crate::searcher::AddSearcher;
|
||||||
}
|
pub use crate::types::Result;
|
||||||
|
61
src/searcher.rs
Normal file
61
src/searcher.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
use rlua::{Context, MetaMethod, RegistryKey, Table, UserData, UserDataMethods, Value};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::types::Result;
|
||||||
|
|
||||||
|
/// Stores Lua modules indexed by module name, and provides an
|
||||||
|
/// `rlua::MetaMethod` to enable `require`ing the stored modules by name
|
||||||
|
/// in an `rlua::Context`.
|
||||||
|
struct Searcher {
|
||||||
|
/// A `HashMap` of Lua modules in `String` representation, indexed
|
||||||
|
/// by module name.
|
||||||
|
modules: HashMap<String, String>,
|
||||||
|
|
||||||
|
/// An `rlua::RegistryKey` whose value is the Lua environment within
|
||||||
|
/// which the user made the request to instantiate a `Searcher` for
|
||||||
|
/// `modules`.
|
||||||
|
globals: RegistryKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Searcher {
|
||||||
|
fn new(modules: HashMap<String, String>, globals: RegistryKey) -> Self {
|
||||||
|
Self { modules, globals }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for Searcher {
|
||||||
|
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::<Table>(&this.globals)?)?
|
||||||
|
.into_function()?,
|
||||||
|
)),
|
||||||
|
None => Ok(Value::Nil),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extend `rlua::Context` to support `require`ing Lua modules by name.
|
||||||
|
pub trait AddSearcher<'a> {
|
||||||
|
/// 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<String, String>) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AddSearcher<'a> for Context<'a> {
|
||||||
|
fn add_searcher(&self, modules: HashMap<String, String>) -> Result<()> {
|
||||||
|
let globals = self.globals();
|
||||||
|
let searchers: Table = globals.get::<_, Table>("package")?.get("searchers")?;
|
||||||
|
let registry_key = self.create_registry_value(globals)?;
|
||||||
|
let searcher = Searcher::new(modules, registry_key);
|
||||||
|
searchers
|
||||||
|
.set(searchers.len()? + 1, searcher)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
}
|
3
src/types.rs
Normal file
3
src/types.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
|
pub type Result<A> = std::result::Result<A, Error>;
|
26
tests/tests.rs
Normal file
26
tests/tests.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use rlua::Lua;
|
||||||
|
use rlua_searcher::{AddSearcher, Result};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let lume = read_lume_to_string();
|
||||||
|
let name = "lume".to_string();
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(name, lume);
|
||||||
|
|
||||||
|
let lua = Lua::new();
|
||||||
|
|
||||||
|
let hello = lua
|
||||||
|
.context::<_, Result<String>>(|lua_ctx| {
|
||||||
|
lua_ctx.add_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()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user