From 278a3bb1400c4556834357bcd774c9e43fa745ac Mon Sep 17 00:00:00 2001 From: Andy Weidenbaum Date: Sat, 27 Feb 2021 11:10:50 +1100 Subject: [PATCH] rearchitect PathSearcher as PolySearcher to genericize conversion of paths to lua source code - which facilitates module reloading for e.g. - fennel - teal - typescripttolua --- src/searcher.rs | 67 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 14 deletions(-) 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())