From c9571d375ad3c3a1fca017397e6ccc3b4c305532 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 6 May 2020 00:09:04 +0800 Subject: [PATCH] Add position to script error. --- README.md | 7 +++++++ src/api.rs | 18 ++++++++++++++---- src/engine.rs | 5 ++++- src/result.rs | 14 +++++++++----- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5de326f1..d8c70be3 100644 --- a/README.md +++ b/README.md @@ -2120,6 +2120,13 @@ Built-in module resolvers are grouped under the `rhai::module_resolvers` module | `StaticModuleResolver` | Loads modules that are statically added. This can be used when the [`no_std`] feature is turned on. | | `NullModuleResolver` | The default module resolution service under the [`no_std`] feature. Always returns an `EvalAltResult::ErrorModuleNotFound` error. | +An [`Engine`]'s module resolver is set via a call to `set_module_resolver`: + +```rust +// Use the 'NullModuleResolver' +engine.set_module_resolver(rhai::module_resolvers::NullModuleResolver::new()); +``` + Script optimization =================== diff --git a/src/api.rs b/src/api.rs index 13c3a399..abc4d37f 100644 --- a/src/api.rs +++ b/src/api.rs @@ -437,13 +437,23 @@ impl Engine { /// Read the contents of a file into a string. #[cfg(not(feature = "no_std"))] fn read_file(path: PathBuf) -> Result> { - let mut f = File::open(path.clone()) - .map_err(|err| Box::new(EvalAltResult::ErrorReadingScriptFile(path.clone(), err)))?; + let mut f = File::open(path.clone()).map_err(|err| { + Box::new(EvalAltResult::ErrorReadingScriptFile( + path.clone(), + Position::none(), + err, + )) + })?; let mut contents = String::new(); - f.read_to_string(&mut contents) - .map_err(|err| Box::new(EvalAltResult::ErrorReadingScriptFile(path.clone(), err)))?; + f.read_to_string(&mut contents).map_err(|err| { + Box::new(EvalAltResult::ErrorReadingScriptFile( + path.clone(), + Position::none(), + err, + )) + })?; Ok(contents) } diff --git a/src/engine.rs b/src/engine.rs index c68efd95..a7beada9 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1530,7 +1530,10 @@ impl Engine { .eval_expr(scope, state, fn_lib, expr, level)? .try_cast::() { - let module = self.module_resolver.resolve(self, &path)?; + let module = self + .module_resolver + .resolve(self, &path) + .map_err(|err| EvalAltResult::set_position(err, expr.position()))?; // TODO - avoid copying module name in inner block? let mod_name = name.as_ref().clone(); diff --git a/src/result.rs b/src/result.rs index 93846eb0..5e38f8d9 100644 --- a/src/result.rs +++ b/src/result.rs @@ -29,7 +29,7 @@ pub enum EvalAltResult { /// /// Never appears under the `no_std` feature. #[cfg(not(feature = "no_std"))] - ErrorReadingScriptFile(PathBuf, std::io::Error), + ErrorReadingScriptFile(PathBuf, Position, std::io::Error), /// Call to an unknown function. Wrapped value is the name of the function. ErrorFunctionNotFound(String, Position), @@ -94,7 +94,7 @@ impl EvalAltResult { pub(crate) fn desc(&self) -> &str { match self { #[cfg(not(feature = "no_std"))] - Self::ErrorReadingScriptFile(_, _) => "Cannot read from script file", + Self::ErrorReadingScriptFile(_, _, _) => "Cannot read from script file", Self::ErrorParsing(p) => p.desc(), Self::ErrorFunctionNotFound(_, _) => "Function not found", @@ -150,9 +150,13 @@ impl fmt::Display for EvalAltResult { match self { #[cfg(not(feature = "no_std"))] - Self::ErrorReadingScriptFile(path, err) => { + Self::ErrorReadingScriptFile(path, pos, err) if pos.is_none() => { write!(f, "{} '{}': {}", desc, path.display(), err) } + #[cfg(not(feature = "no_std"))] + Self::ErrorReadingScriptFile(path, pos, err) => { + write!(f, "{} '{}': {} ({})", desc, path.display(), err, pos) + } Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p), @@ -261,7 +265,7 @@ impl EvalAltResult { pub fn position(&self) -> Position { match self { #[cfg(not(feature = "no_std"))] - Self::ErrorReadingScriptFile(_, _) => Position::none(), + Self::ErrorReadingScriptFile(_, pos, _) => *pos, Self::ErrorParsing(err) => err.position(), @@ -297,7 +301,7 @@ impl EvalAltResult { pub(crate) fn set_position(mut err: Box, new_position: Position) -> Box { match err.as_mut() { #[cfg(not(feature = "no_std"))] - Self::ErrorReadingScriptFile(_, _) => (), + Self::ErrorReadingScriptFile(_, pos, _) => *pos = new_position, Self::ErrorParsing(err) => err.1 = new_position,