From e3e53bd3991354c737a1c2fce8ee4d2c51f0b7e1 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 2 Mar 2021 15:02:28 +0800 Subject: [PATCH] Introduce RhaiResult. --- CHANGELOG.md | 2 +- src/builtin.rs | 8 ++++---- src/engine.rs | 26 +++++++++----------------- src/engine_api.rs | 16 ++++++++-------- src/fn_call.rs | 13 +++++++------ src/fn_native.rs | 11 +++++------ src/fn_register.rs | 12 +++++------- src/lib.rs | 2 ++ src/plugin.rs | 8 ++------ src/serde/ser.rs | 4 ++-- src/syntax.rs | 22 ++++++---------------- tests/native.rs | 7 ++----- tests/plugins.rs | 2 +- 13 files changed, 54 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db427187..05033bb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -724,7 +724,7 @@ Breaking changes ---------------- * `Engine::compile_XXX` functions now return `ParseError` instead of `Box`. -* The `RegisterDynamicFn` trait is merged into the `RegisterResultFn` trait which now always returns `Result>`. +* The `RegisterDynamicFn` trait is merged into the `RegisterResultFn` trait which now always returns `RhaiResult`. * Default maximum limit on levels of nested function calls is fine-tuned and set to a different value. * Some operator functions are now built in (see _Speed enhancements_ below), so they are available even under `Engine::new_raw`. * Strings are now immutable. The type `rhai::ImmutableString` is used instead of `std::string::String`. This is to avoid excessive cloning of strings. All native-Rust functions taking string parameters should switch to `rhai::ImmutableString` (which is either `Rc` or `Arc` depending on whether the `sync` feature is used). diff --git a/src/builtin.rs b/src/builtin.rs index b2a17037..6090ec07 100644 --- a/src/builtin.rs +++ b/src/builtin.rs @@ -1,8 +1,8 @@ //! Built-in implementations for common operators. use crate::fn_native::{FnCallArgs, NativeCallContext}; -use crate::stdlib::{any::TypeId, boxed::Box, format, string::ToString}; -use crate::{Dynamic, EvalAltResult, ImmutableString, INT}; +use crate::stdlib::{any::TypeId, format, string::ToString}; +use crate::{Dynamic, ImmutableString, RhaiResult, INT}; #[cfg(not(feature = "no_float"))] use crate::FLOAT; @@ -19,7 +19,7 @@ pub fn get_builtin_binary_op_fn( op: &str, x: &Dynamic, y: &Dynamic, -) -> Option Result>> { +) -> Option RhaiResult> { let type1 = x.type_id(); let type2 = y.type_id(); @@ -792,7 +792,7 @@ pub fn get_builtin_op_assignment_fn( op: &str, x: &Dynamic, y: &Dynamic, -) -> Option Result>> { +) -> Option RhaiResult> { let type1 = x.type_id(); let type2 = y.type_id(); diff --git a/src/engine.rs b/src/engine.rs index c7cf53e9..a3d09842 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -25,8 +25,8 @@ use crate::stdlib::{ use crate::syntax::CustomSyntax; use crate::utils::{get_hasher, StraightHasherBuilder}; use crate::{ - calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope, - Shared, StaticVec, + calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, + RhaiResult, Scope, Shared, StaticVec, }; #[cfg(not(feature = "no_index"))] @@ -1385,7 +1385,7 @@ impl Engine { expr: &Expr, level: usize, new_val: Option<((Dynamic, Position), (&str, Position))>, - ) -> Result> { + ) -> RhaiResult { let (crate::ast::BinaryExpr { lhs, rhs }, chain_type, op_pos) = match expr { Expr::Index(x, pos) => (x.as_ref(), ChainType::Index, *pos), Expr::Dot(x, pos) => (x.as_ref(), ChainType::Dot, *pos), @@ -1649,7 +1649,7 @@ impl Engine { lhs: &Expr, rhs: &Expr, level: usize, - ) -> Result> { + ) -> RhaiResult { self.inc_operations(state, rhs.position())?; let lhs_value = self.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?; @@ -1707,7 +1707,7 @@ impl Engine { this_ptr: &mut Option<&mut Dynamic>, expr: &Expr, level: usize, - ) -> Result> { + ) -> RhaiResult { self.inc_operations(state, expr.position())?; let result = match expr { @@ -1876,7 +1876,7 @@ impl Engine { statements: &[Stmt], restore: bool, level: usize, - ) -> Result> { + ) -> RhaiResult { let mut _has_imports = false; let prev_always_search = state.always_search; let prev_scope_len = scope.len(); @@ -1992,7 +1992,7 @@ impl Engine { this_ptr: &mut Option<&mut Dynamic>, stmt: &Stmt, level: usize, - ) -> Result> { + ) -> RhaiResult { self.inc_operations(state, stmt.position())?; let result = match stmt { @@ -2467,21 +2467,13 @@ impl Engine { /// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards. #[cfg(feature = "unchecked")] #[inline(always)] - fn check_data_size( - &self, - result: Result>, - _pos: Position, - ) -> Result> { + fn check_data_size(&self, result: RhaiResult, _pos: Position) -> RhaiResult { result } /// Check a result to ensure that the data size is within allowable limit. #[cfg(not(feature = "unchecked"))] - fn check_data_size( - &self, - result: Result>, - pos: Position, - ) -> Result> { + fn check_data_size(&self, result: RhaiResult, pos: Position) -> RhaiResult { // Simply return all errors if result.is_err() { return result; diff --git a/src/engine_api.rs b/src/engine_api.rs index 058e8ee0..2e8e31f6 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -13,7 +13,7 @@ use crate::stdlib::{ }; use crate::{ scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Module, NativeCallContext, - ParseError, Position, Shared, AST, + ParseError, Position, RhaiResult, Shared, AST, }; #[cfg(not(feature = "no_index"))] @@ -217,7 +217,7 @@ impl Engine { /// impl TestStruct { /// fn new() -> Self { Self { field: 1 } } /// // Even a getter must start with `&mut self` and not `&self`. - /// fn get_field(&mut self) -> Result> { + /// fn get_field(&mut self) -> RhaiResult { /// Ok(self.field.into()) /// } /// } @@ -241,7 +241,7 @@ impl Engine { pub fn register_get_result( &mut self, name: &str, - get_fn: impl Fn(&mut T) -> Result> + SendSync + 'static, + get_fn: impl Fn(&mut T) -> RhaiResult + SendSync + 'static, ) -> &mut Self { use crate::{engine::make_getter, RegisterResultFn}; self.register_result_fn(&make_getter(name), get_fn) @@ -474,7 +474,7 @@ impl Engine { /// impl TestStruct { /// fn new() -> Self { Self { fields: vec![1, 2, 3, 4, 5] } } /// // Even a getter must start with `&mut self` and not `&self`. - /// fn get_field(&mut self, index: i64) -> Result> { + /// fn get_field(&mut self, index: i64) -> RhaiResult { /// Ok(self.fields[index as usize].into()) /// } /// } @@ -499,7 +499,7 @@ impl Engine { #[inline(always)] pub fn register_indexer_get_result( &mut self, - get_fn: impl Fn(&mut T, X) -> Result> + SendSync + 'static, + get_fn: impl Fn(&mut T, X) -> RhaiResult + SendSync + 'static, ) -> &mut Self { if TypeId::of::() == TypeId::of::() { panic!("Cannot register indexer for arrays."); @@ -1518,7 +1518,7 @@ impl Engine { mods: &mut Imports, ast: &'a AST, level: usize, - ) -> Result> { + ) -> RhaiResult { let mut state: State = Default::default(); state.source = ast.clone_source(); #[cfg(not(feature = "no_module"))] @@ -1733,7 +1733,7 @@ impl Engine { name: &str, mut this_ptr: Option<&mut Dynamic>, mut arg_values: impl AsMut<[Dynamic]>, - ) -> Result> { + ) -> RhaiResult { let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect(); self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, args.as_mut()) @@ -1756,7 +1756,7 @@ impl Engine { name: &str, this_ptr: &mut Option<&mut Dynamic>, args: &mut FnCallArgs, - ) -> Result> { + ) -> RhaiResult { let state = &mut Default::default(); let mods = &mut Default::default(); let lib = &[ast.lib()]; diff --git a/src/fn_call.rs b/src/fn_call.rs index abd5718c..11bc7ac1 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -24,6 +24,7 @@ use crate::utils::combine_hashes; use crate::{ ast::{Expr, Stmt}, fn_native::CallableFunction, + RhaiResult, }; use crate::{ calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr, @@ -468,7 +469,7 @@ impl Engine { args: &mut FnCallArgs, pos: Position, level: usize, - ) -> Result> { + ) -> RhaiResult { #[inline(always)] fn make_error( name: crate::stdlib::string::String, @@ -476,7 +477,7 @@ impl Engine { state: &State, err: Box, pos: Position, - ) -> Result> { + ) -> RhaiResult { Err(Box::new(EvalAltResult::ErrorInFunctionCall( name, fn_def @@ -817,7 +818,7 @@ impl Engine { statements: &[Stmt], lib: &[&Module], level: usize, - ) -> Result> { + ) -> RhaiResult { self.eval_stmt_block(scope, mods, state, lib, &mut None, statements, false, level) .or_else(|err| match *err { EvalAltResult::Return(out, _) => Ok(out), @@ -838,7 +839,7 @@ impl Engine { script: &str, pos: Position, level: usize, - ) -> Result> { + ) -> RhaiResult { self.inc_operations(state, pos)?; let script = script.trim(); @@ -1026,7 +1027,7 @@ impl Engine { pos: Position, capture_scope: bool, level: usize, - ) -> Result> { + ) -> RhaiResult { let args_expr = args_expr.as_ref(); // Handle call() - Redirect function call @@ -1276,7 +1277,7 @@ impl Engine { hash_script: NonZeroU64, pos: Position, level: usize, - ) -> Result> { + ) -> RhaiResult { let args_expr = args_expr.as_ref(); let namespace = namespace.unwrap(); diff --git a/src/fn_native.rs b/src/fn_native.rs index 65805e36..728c8765 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -15,7 +15,7 @@ use crate::stdlib::{ use crate::token::is_valid_identifier; use crate::{ calc_script_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, - Position, + Position, RhaiResult, }; #[cfg(not(feature = "sync"))] @@ -185,7 +185,7 @@ impl<'e, 'n, 's, 'a, 'm> NativeCallContext<'e, 'n, 's, 'a, 'm> { fn_name: &str, is_method: bool, args: &mut [&mut Dynamic], - ) -> Result> { + ) -> RhaiResult { self.engine() .exec_fn_call( &mut self.mods.cloned().unwrap_or_default(), @@ -317,7 +317,7 @@ impl FnPtr { ctx: NativeCallContext, this_ptr: Option<&mut Dynamic>, mut arg_values: impl AsMut<[Dynamic]>, - ) -> Result> { + ) -> RhaiResult { let arg_values = arg_values.as_mut(); let mut args_data = self @@ -381,11 +381,10 @@ impl TryFrom<&str> for FnPtr { /// A general function trail object. #[cfg(not(feature = "sync"))] -pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> Result>; +pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult; /// A general function trail object. #[cfg(feature = "sync")] -pub type FnAny = - dyn Fn(NativeCallContext, &mut FnCallArgs) -> Result> + Send + Sync; +pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult + Send + Sync; /// A standard function that gets an iterator from a type. pub type IteratorFn = fn(Dynamic) -> Box>; diff --git a/src/fn_register.rs b/src/fn_register.rs index 4021fa57..b63572b1 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -7,7 +7,7 @@ use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync}; use crate::r#unsafe::unsafe_cast_box; use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String}; use crate::{ - Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, NativeCallContext, + Dynamic, Engine, FnAccess, FnNamespace, ImmutableString, NativeCallContext, RhaiResult, }; /// Trait to register custom functions with the [`Engine`]. @@ -52,7 +52,7 @@ pub trait RegisterResultFn { /// use rhai::{Engine, Dynamic, RegisterResultFn, EvalAltResult}; /// /// // Normal function - /// fn div(x: i64, y: i64) -> Result> { + /// fn div(x: i64, y: i64) -> RhaiResult { /// if y == 0 { /// // '.into()' automatically converts to 'Box' /// Err("division by zero!".into()) @@ -142,15 +142,13 @@ macro_rules! make_func { /// To Dynamic mapping function. #[inline(always)] -pub fn map_dynamic(data: impl Variant + Clone) -> Result> { +pub fn map_dynamic(data: impl Variant + Clone) -> RhaiResult { Ok(data.into_dynamic()) } /// To Dynamic mapping function. #[inline(always)] -pub fn map_result( - data: Result>, -) -> Result> { +pub fn map_result(data: RhaiResult) -> RhaiResult { data } @@ -197,7 +195,7 @@ macro_rules! def_register { impl< $($par: Variant + Clone,)* - FN: Fn($($param),*) -> Result> + SendSync + 'static, + FN: Fn($($param),*) -> RhaiResult + SendSync + 'static, > RegisterResultFn for Engine { #[inline] diff --git a/src/lib.rs b/src/lib.rs index e809e254..aee23e1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,8 @@ mod token; mod r#unsafe; mod utils; +pub type RhaiResult = Result>; + /// The system integer type. It is defined as [`i64`]. /// /// If the `only_i32` feature is enabled, this will be [`i32`] instead. diff --git a/src/plugin.rs b/src/plugin.rs index a46afdc4..d5fcac4f 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -4,7 +4,7 @@ pub use crate::fn_native::{CallableFunction, FnCallArgs}; pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString, vec as new_vec}; pub use crate::{ Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module, - NativeCallContext, Position, RegisterFn, RegisterResultFn, + NativeCallContext, Position, RegisterFn, RegisterResultFn, RhaiResult, }; #[cfg(not(features = "no_module"))] @@ -18,11 +18,7 @@ pub use rhai_codegen::{export_fn, register_exported_fn}; /// Use the `#[export_module]` and `#[export_fn]` procedural attributes instead. pub trait PluginFunction { /// Call the plugin function with the arguments provided. - fn call( - &self, - context: NativeCallContext, - args: &mut FnCallArgs, - ) -> Result>; + fn call(&self, context: NativeCallContext, args: &mut FnCallArgs) -> RhaiResult; /// Is this plugin function a method? fn is_method_call(&self) -> bool; diff --git a/src/serde/ser.rs b/src/serde/ser.rs index a833c3b4..c326356a 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -79,7 +79,7 @@ impl DynamicSerializer { /// # Ok(()) /// # } /// ``` -pub fn to_dynamic(value: T) -> Result> { +pub fn to_dynamic(value: T) -> RhaiResult { let mut s = DynamicSerializer::new(Default::default()); value.serialize(&mut s) } @@ -690,7 +690,7 @@ impl serde::ser::SerializeStructVariant for StructVariantSerializer { } #[cfg(not(feature = "no_object"))] -fn make_variant(variant: &'static str, value: Dynamic) -> Result> { +fn make_variant(variant: &'static str, value: Dynamic) -> RhaiResult { let mut map = Map::with_capacity(1); map.insert(variant.into(), value); Ok(map.into()) diff --git a/src/syntax.rs b/src/syntax.rs index 4f276370..e126af0a 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -6,8 +6,7 @@ use crate::fn_native::SendSync; use crate::stdlib::{boxed::Box, format, string::ToString}; use crate::token::{is_valid_identifier, Token}; use crate::{ - Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseError, Position, Shared, - StaticVec, + Engine, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared, StaticVec, }; pub const MARKER_EXPR: &str = "$expr$"; @@ -16,12 +15,10 @@ pub const MARKER_IDENT: &str = "$ident$"; /// A general expression evaluation trait object. #[cfg(not(feature = "sync"))] -pub type FnCustomSyntaxEval = - dyn Fn(&mut EvalContext, &[Expression]) -> Result>; +pub type FnCustomSyntaxEval = dyn Fn(&mut EvalContext, &[Expression]) -> RhaiResult; /// A general expression evaluation trait object. #[cfg(feature = "sync")] -pub type FnCustomSyntaxEval = - dyn Fn(&mut EvalContext, &[Expression]) -> Result> + Send + Sync; +pub type FnCustomSyntaxEval = dyn Fn(&mut EvalContext, &[Expression]) -> RhaiResult + Send + Sync; /// A general expression parsing trait object. #[cfg(not(feature = "sync"))] @@ -68,10 +65,7 @@ impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_> { /// /// This function is very low level. It evaluates an expression from an [`AST`][crate::AST]. #[inline(always)] - pub fn eval_expression_tree( - &mut self, - expr: &Expression, - ) -> Result> { + pub fn eval_expression_tree(&mut self, expr: &Expression) -> RhaiResult { self.engine.eval_expr( self.scope, self.mods, @@ -113,9 +107,7 @@ impl Engine { &mut self, keywords: &[S], new_vars: isize, - func: impl Fn(&mut EvalContext, &[Expression]) -> Result> - + SendSync - + 'static, + func: impl Fn(&mut EvalContext, &[Expression]) -> RhaiResult + SendSync + 'static, ) -> Result<&mut Self, ParseError> { let keywords = keywords.as_ref(); @@ -234,9 +226,7 @@ impl Engine { + SendSync + 'static, new_vars: isize, - func: impl Fn(&mut EvalContext, &[Expression]) -> Result> - + SendSync - + 'static, + func: impl Fn(&mut EvalContext, &[Expression]) -> RhaiResult + SendSync + 'static, ) -> &mut Self { let syntax = CustomSyntax { parse: Box::new(parse), diff --git a/tests/native.rs b/tests/native.rs index 209c4a57..ee1506aa 100644 --- a/tests/native.rs +++ b/tests/native.rs @@ -1,12 +1,9 @@ -use rhai::{Dynamic, Engine, EvalAltResult, NativeCallContext, INT}; +use rhai::{Dynamic, Engine, EvalAltResult, NativeCallContext, RhaiResult, INT}; use std::any::TypeId; #[test] fn test_native_context() -> Result<(), Box> { - fn add_double( - context: NativeCallContext, - args: &mut [&mut Dynamic], - ) -> Result> { + fn add_double(context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult { let x = args[0].as_int().unwrap(); let y = args[1].as_int().unwrap(); Ok(format!("{}_{}", context.fn_name(), x + 2 * y).into()) diff --git a/tests/plugins.rs b/tests/plugins.rs index e42c4c73..b4cbc708 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -18,7 +18,7 @@ mod test { #[rhai_fn(get = "foo", return_raw)] #[inline(always)] - pub fn foo(array: &mut Array) -> Result> { + pub fn foo(array: &mut Array) -> RhaiResult { Ok(array[0].clone()) } }