Introduce RhaiResult.

This commit is contained in:
Stephen Chung 2021-03-02 15:02:28 +08:00
parent 521c8fad27
commit e3e53bd399
13 changed files with 54 additions and 79 deletions

View File

@ -724,7 +724,7 @@ Breaking changes
---------------- ----------------
* `Engine::compile_XXX` functions now return `ParseError` instead of `Box<ParseError>`. * `Engine::compile_XXX` functions now return `ParseError` instead of `Box<ParseError>`.
* The `RegisterDynamicFn` trait is merged into the `RegisterResultFn` trait which now always returns `Result<Dynamic, Box<EvalAltResult>>`. * 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. * 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`. * 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<String>` or `Arc<String>` depending on whether the `sync` feature is used). * 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<String>` or `Arc<String>` depending on whether the `sync` feature is used).

View File

@ -1,8 +1,8 @@
//! Built-in implementations for common operators. //! Built-in implementations for common operators.
use crate::fn_native::{FnCallArgs, NativeCallContext}; use crate::fn_native::{FnCallArgs, NativeCallContext};
use crate::stdlib::{any::TypeId, boxed::Box, format, string::ToString}; use crate::stdlib::{any::TypeId, format, string::ToString};
use crate::{Dynamic, EvalAltResult, ImmutableString, INT}; use crate::{Dynamic, ImmutableString, RhaiResult, INT};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
@ -19,7 +19,7 @@ pub fn get_builtin_binary_op_fn(
op: &str, op: &str,
x: &Dynamic, x: &Dynamic,
y: &Dynamic, y: &Dynamic,
) -> Option<fn(NativeCallContext, &mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>> { ) -> Option<fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult> {
let type1 = x.type_id(); let type1 = x.type_id();
let type2 = y.type_id(); let type2 = y.type_id();
@ -792,7 +792,7 @@ pub fn get_builtin_op_assignment_fn(
op: &str, op: &str,
x: &Dynamic, x: &Dynamic,
y: &Dynamic, y: &Dynamic,
) -> Option<fn(NativeCallContext, &mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>> { ) -> Option<fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult> {
let type1 = x.type_id(); let type1 = x.type_id();
let type2 = y.type_id(); let type2 = y.type_id();

View File

@ -25,8 +25,8 @@ use crate::stdlib::{
use crate::syntax::CustomSyntax; use crate::syntax::CustomSyntax;
use crate::utils::{get_hasher, StraightHasherBuilder}; use crate::utils::{get_hasher, StraightHasherBuilder};
use crate::{ use crate::{
calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position, Scope, calc_native_fn_hash, Dynamic, EvalAltResult, FnPtr, ImmutableString, Module, Position,
Shared, StaticVec, RhaiResult, Scope, Shared, StaticVec,
}; };
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
@ -1385,7 +1385,7 @@ impl Engine {
expr: &Expr, expr: &Expr,
level: usize, level: usize,
new_val: Option<((Dynamic, Position), (&str, Position))>, new_val: Option<((Dynamic, Position), (&str, Position))>,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let (crate::ast::BinaryExpr { lhs, rhs }, chain_type, op_pos) = match expr { let (crate::ast::BinaryExpr { lhs, rhs }, chain_type, op_pos) = match expr {
Expr::Index(x, pos) => (x.as_ref(), ChainType::Index, *pos), Expr::Index(x, pos) => (x.as_ref(), ChainType::Index, *pos),
Expr::Dot(x, pos) => (x.as_ref(), ChainType::Dot, *pos), Expr::Dot(x, pos) => (x.as_ref(), ChainType::Dot, *pos),
@ -1649,7 +1649,7 @@ impl Engine {
lhs: &Expr, lhs: &Expr,
rhs: &Expr, rhs: &Expr,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.inc_operations(state, rhs.position())?; self.inc_operations(state, rhs.position())?;
let lhs_value = self.eval_expr(scope, mods, state, lib, this_ptr, lhs, level)?; 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>, this_ptr: &mut Option<&mut Dynamic>,
expr: &Expr, expr: &Expr,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.inc_operations(state, expr.position())?; self.inc_operations(state, expr.position())?;
let result = match expr { let result = match expr {
@ -1876,7 +1876,7 @@ impl Engine {
statements: &[Stmt], statements: &[Stmt],
restore: bool, restore: bool,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let mut _has_imports = false; let mut _has_imports = false;
let prev_always_search = state.always_search; let prev_always_search = state.always_search;
let prev_scope_len = scope.len(); let prev_scope_len = scope.len();
@ -1992,7 +1992,7 @@ impl Engine {
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
stmt: &Stmt, stmt: &Stmt,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.inc_operations(state, stmt.position())?; self.inc_operations(state, stmt.position())?;
let result = match stmt { let result = match stmt {
@ -2467,21 +2467,13 @@ impl Engine {
/// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards. /// [`Position`] in [`EvalAltResult`] may be None and should be set afterwards.
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
#[inline(always)] #[inline(always)]
fn check_data_size( fn check_data_size(&self, result: RhaiResult, _pos: Position) -> RhaiResult {
&self,
result: Result<Dynamic, Box<EvalAltResult>>,
_pos: Position,
) -> Result<Dynamic, Box<EvalAltResult>> {
result result
} }
/// Check a result to ensure that the data size is within allowable limit. /// Check a result to ensure that the data size is within allowable limit.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
fn check_data_size( fn check_data_size(&self, result: RhaiResult, pos: Position) -> RhaiResult {
&self,
result: Result<Dynamic, Box<EvalAltResult>>,
pos: Position,
) -> Result<Dynamic, Box<EvalAltResult>> {
// Simply return all errors // Simply return all errors
if result.is_err() { if result.is_err() {
return result; return result;

View File

@ -13,7 +13,7 @@ use crate::stdlib::{
}; };
use crate::{ use crate::{
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Module, NativeCallContext, scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Module, NativeCallContext,
ParseError, Position, Shared, AST, ParseError, Position, RhaiResult, Shared, AST,
}; };
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
@ -217,7 +217,7 @@ impl Engine {
/// impl TestStruct { /// impl TestStruct {
/// fn new() -> Self { Self { field: 1 } } /// fn new() -> Self { Self { field: 1 } }
/// // Even a getter must start with `&mut self` and not `&self`. /// // Even a getter must start with `&mut self` and not `&self`.
/// fn get_field(&mut self) -> Result<Dynamic, Box<EvalAltResult>> { /// fn get_field(&mut self) -> RhaiResult {
/// Ok(self.field.into()) /// Ok(self.field.into())
/// } /// }
/// } /// }
@ -241,7 +241,7 @@ impl Engine {
pub fn register_get_result<T: Variant + Clone>( pub fn register_get_result<T: Variant + Clone>(
&mut self, &mut self,
name: &str, name: &str,
get_fn: impl Fn(&mut T) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static, get_fn: impl Fn(&mut T) -> RhaiResult + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
use crate::{engine::make_getter, RegisterResultFn}; use crate::{engine::make_getter, RegisterResultFn};
self.register_result_fn(&make_getter(name), get_fn) self.register_result_fn(&make_getter(name), get_fn)
@ -474,7 +474,7 @@ impl Engine {
/// impl TestStruct { /// impl TestStruct {
/// fn new() -> Self { Self { fields: vec![1, 2, 3, 4, 5] } } /// fn new() -> Self { Self { fields: vec![1, 2, 3, 4, 5] } }
/// // Even a getter must start with `&mut self` and not `&self`. /// // Even a getter must start with `&mut self` and not `&self`.
/// fn get_field(&mut self, index: i64) -> Result<Dynamic, Box<EvalAltResult>> { /// fn get_field(&mut self, index: i64) -> RhaiResult {
/// Ok(self.fields[index as usize].into()) /// Ok(self.fields[index as usize].into())
/// } /// }
/// } /// }
@ -499,7 +499,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn register_indexer_get_result<T: Variant + Clone, X: Variant + Clone>( pub fn register_indexer_get_result<T: Variant + Clone, X: Variant + Clone>(
&mut self, &mut self,
get_fn: impl Fn(&mut T, X) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static, get_fn: impl Fn(&mut T, X) -> RhaiResult + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
if TypeId::of::<T>() == TypeId::of::<Array>() { if TypeId::of::<T>() == TypeId::of::<Array>() {
panic!("Cannot register indexer for arrays."); panic!("Cannot register indexer for arrays.");
@ -1518,7 +1518,7 @@ impl Engine {
mods: &mut Imports, mods: &mut Imports,
ast: &'a AST, ast: &'a AST,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let mut state: State = Default::default(); let mut state: State = Default::default();
state.source = ast.clone_source(); state.source = ast.clone_source();
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
@ -1733,7 +1733,7 @@ impl Engine {
name: &str, name: &str,
mut this_ptr: Option<&mut Dynamic>, mut this_ptr: Option<&mut Dynamic>,
mut arg_values: impl AsMut<[Dynamic]>, mut arg_values: impl AsMut<[Dynamic]>,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect(); 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()) self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, args.as_mut())
@ -1756,7 +1756,7 @@ impl Engine {
name: &str, name: &str,
this_ptr: &mut Option<&mut Dynamic>, this_ptr: &mut Option<&mut Dynamic>,
args: &mut FnCallArgs, args: &mut FnCallArgs,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let state = &mut Default::default(); let state = &mut Default::default();
let mods = &mut Default::default(); let mods = &mut Default::default();
let lib = &[ast.lib()]; let lib = &[ast.lib()];

View File

@ -24,6 +24,7 @@ use crate::utils::combine_hashes;
use crate::{ use crate::{
ast::{Expr, Stmt}, ast::{Expr, Stmt},
fn_native::CallableFunction, fn_native::CallableFunction,
RhaiResult,
}; };
use crate::{ use crate::{
calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr, calc_native_fn_hash, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, FnPtr,
@ -468,7 +469,7 @@ impl Engine {
args: &mut FnCallArgs, args: &mut FnCallArgs,
pos: Position, pos: Position,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
#[inline(always)] #[inline(always)]
fn make_error( fn make_error(
name: crate::stdlib::string::String, name: crate::stdlib::string::String,
@ -476,7 +477,7 @@ impl Engine {
state: &State, state: &State,
err: Box<EvalAltResult>, err: Box<EvalAltResult>,
pos: Position, pos: Position,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
Err(Box::new(EvalAltResult::ErrorInFunctionCall( Err(Box::new(EvalAltResult::ErrorInFunctionCall(
name, name,
fn_def fn_def
@ -817,7 +818,7 @@ impl Engine {
statements: &[Stmt], statements: &[Stmt],
lib: &[&Module], lib: &[&Module],
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.eval_stmt_block(scope, mods, state, lib, &mut None, statements, false, level) self.eval_stmt_block(scope, mods, state, lib, &mut None, statements, false, level)
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::Return(out, _) => Ok(out), EvalAltResult::Return(out, _) => Ok(out),
@ -838,7 +839,7 @@ impl Engine {
script: &str, script: &str,
pos: Position, pos: Position,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.inc_operations(state, pos)?; self.inc_operations(state, pos)?;
let script = script.trim(); let script = script.trim();
@ -1026,7 +1027,7 @@ impl Engine {
pos: Position, pos: Position,
capture_scope: bool, capture_scope: bool,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let args_expr = args_expr.as_ref(); let args_expr = args_expr.as_ref();
// Handle call() - Redirect function call // Handle call() - Redirect function call
@ -1276,7 +1277,7 @@ impl Engine {
hash_script: NonZeroU64, hash_script: NonZeroU64,
pos: Position, pos: Position,
level: usize, level: usize,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let args_expr = args_expr.as_ref(); let args_expr = args_expr.as_ref();
let namespace = namespace.unwrap(); let namespace = namespace.unwrap();

View File

@ -15,7 +15,7 @@ use crate::stdlib::{
use crate::token::is_valid_identifier; use crate::token::is_valid_identifier;
use crate::{ use crate::{
calc_script_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module, calc_script_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, ImmutableString, Module,
Position, Position, RhaiResult,
}; };
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
@ -185,7 +185,7 @@ impl<'e, 'n, 's, 'a, 'm> NativeCallContext<'e, 'n, 's, 'a, 'm> {
fn_name: &str, fn_name: &str,
is_method: bool, is_method: bool,
args: &mut [&mut Dynamic], args: &mut [&mut Dynamic],
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
self.engine() self.engine()
.exec_fn_call( .exec_fn_call(
&mut self.mods.cloned().unwrap_or_default(), &mut self.mods.cloned().unwrap_or_default(),
@ -317,7 +317,7 @@ impl FnPtr {
ctx: NativeCallContext, ctx: NativeCallContext,
this_ptr: Option<&mut Dynamic>, this_ptr: Option<&mut Dynamic>,
mut arg_values: impl AsMut<[Dynamic]>, mut arg_values: impl AsMut<[Dynamic]>,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> RhaiResult {
let arg_values = arg_values.as_mut(); let arg_values = arg_values.as_mut();
let mut args_data = self let mut args_data = self
@ -381,11 +381,10 @@ impl TryFrom<&str> for FnPtr {
/// A general function trail object. /// A general function trail object.
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>>; pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult;
/// A general function trail object. /// A general function trail object.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type FnAny = pub type FnAny = dyn Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResult + Send + Sync;
dyn Fn(NativeCallContext, &mut FnCallArgs) -> Result<Dynamic, Box<EvalAltResult>> + Send + Sync;
/// A standard function that gets an iterator from a type. /// A standard function that gets an iterator from a type.
pub type IteratorFn = fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>; pub type IteratorFn = fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;

View File

@ -7,7 +7,7 @@ use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
use crate::r#unsafe::unsafe_cast_box; use crate::r#unsafe::unsafe_cast_box;
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String}; use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String};
use crate::{ use crate::{
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, NativeCallContext, Dynamic, Engine, FnAccess, FnNamespace, ImmutableString, NativeCallContext, RhaiResult,
}; };
/// Trait to register custom functions with the [`Engine`]. /// Trait to register custom functions with the [`Engine`].
@ -52,7 +52,7 @@ pub trait RegisterResultFn<FN, ARGS> {
/// use rhai::{Engine, Dynamic, RegisterResultFn, EvalAltResult}; /// use rhai::{Engine, Dynamic, RegisterResultFn, EvalAltResult};
/// ///
/// // Normal function /// // Normal function
/// fn div(x: i64, y: i64) -> Result<Dynamic, Box<EvalAltResult>> { /// fn div(x: i64, y: i64) -> RhaiResult {
/// if y == 0 { /// if y == 0 {
/// // '.into()' automatically converts to 'Box<EvalAltResult::ErrorRuntime>' /// // '.into()' automatically converts to 'Box<EvalAltResult::ErrorRuntime>'
/// Err("division by zero!".into()) /// Err("division by zero!".into())
@ -142,15 +142,13 @@ macro_rules! make_func {
/// To Dynamic mapping function. /// To Dynamic mapping function.
#[inline(always)] #[inline(always)]
pub fn map_dynamic(data: impl Variant + Clone) -> Result<Dynamic, Box<EvalAltResult>> { pub fn map_dynamic(data: impl Variant + Clone) -> RhaiResult {
Ok(data.into_dynamic()) Ok(data.into_dynamic())
} }
/// To Dynamic mapping function. /// To Dynamic mapping function.
#[inline(always)] #[inline(always)]
pub fn map_result( pub fn map_result(data: RhaiResult) -> RhaiResult {
data: Result<Dynamic, Box<EvalAltResult>>,
) -> Result<Dynamic, Box<EvalAltResult>> {
data data
} }
@ -197,7 +195,7 @@ macro_rules! def_register {
impl< impl<
$($par: Variant + Clone,)* $($par: Variant + Clone,)*
FN: Fn($($param),*) -> Result<Dynamic, Box<EvalAltResult>> + SendSync + 'static, FN: Fn($($param),*) -> RhaiResult + SendSync + 'static,
> RegisterResultFn<FN, ($($mark,)*)> for Engine > RegisterResultFn<FN, ($($mark,)*)> for Engine
{ {
#[inline] #[inline]

View File

@ -88,6 +88,8 @@ mod token;
mod r#unsafe; mod r#unsafe;
mod utils; mod utils;
pub type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
/// The system integer type. It is defined as [`i64`]. /// The system integer type. It is defined as [`i64`].
/// ///
/// If the `only_i32` feature is enabled, this will be [`i32`] instead. /// If the `only_i32` feature is enabled, this will be [`i32`] instead.

View File

@ -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::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString, vec as new_vec};
pub use crate::{ pub use crate::{
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
NativeCallContext, Position, RegisterFn, RegisterResultFn, NativeCallContext, Position, RegisterFn, RegisterResultFn, RhaiResult,
}; };
#[cfg(not(features = "no_module"))] #[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. /// Use the `#[export_module]` and `#[export_fn]` procedural attributes instead.
pub trait PluginFunction { pub trait PluginFunction {
/// Call the plugin function with the arguments provided. /// Call the plugin function with the arguments provided.
fn call( fn call(&self, context: NativeCallContext, args: &mut FnCallArgs) -> RhaiResult;
&self,
context: NativeCallContext,
args: &mut FnCallArgs,
) -> Result<Dynamic, Box<EvalAltResult>>;
/// Is this plugin function a method? /// Is this plugin function a method?
fn is_method_call(&self) -> bool; fn is_method_call(&self) -> bool;

View File

@ -79,7 +79,7 @@ impl DynamicSerializer {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
pub fn to_dynamic<T: Serialize>(value: T) -> Result<Dynamic, Box<EvalAltResult>> { pub fn to_dynamic<T: Serialize>(value: T) -> RhaiResult {
let mut s = DynamicSerializer::new(Default::default()); let mut s = DynamicSerializer::new(Default::default());
value.serialize(&mut s) value.serialize(&mut s)
} }
@ -690,7 +690,7 @@ impl serde::ser::SerializeStructVariant for StructVariantSerializer {
} }
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
fn make_variant(variant: &'static str, value: Dynamic) -> Result<Dynamic, Box<EvalAltResult>> { fn make_variant(variant: &'static str, value: Dynamic) -> RhaiResult {
let mut map = Map::with_capacity(1); let mut map = Map::with_capacity(1);
map.insert(variant.into(), value); map.insert(variant.into(), value);
Ok(map.into()) Ok(map.into())

View File

@ -6,8 +6,7 @@ use crate::fn_native::SendSync;
use crate::stdlib::{boxed::Box, format, string::ToString}; use crate::stdlib::{boxed::Box, format, string::ToString};
use crate::token::{is_valid_identifier, Token}; use crate::token::{is_valid_identifier, Token};
use crate::{ use crate::{
Dynamic, Engine, EvalAltResult, ImmutableString, LexError, ParseError, Position, Shared, Engine, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared, StaticVec,
StaticVec,
}; };
pub const MARKER_EXPR: &str = "$expr$"; pub const MARKER_EXPR: &str = "$expr$";
@ -16,12 +15,10 @@ pub const MARKER_IDENT: &str = "$ident$";
/// A general expression evaluation trait object. /// A general expression evaluation trait object.
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type FnCustomSyntaxEval = pub type FnCustomSyntaxEval = dyn Fn(&mut EvalContext, &[Expression]) -> RhaiResult;
dyn Fn(&mut EvalContext, &[Expression]) -> Result<Dynamic, Box<EvalAltResult>>;
/// A general expression evaluation trait object. /// A general expression evaluation trait object.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type FnCustomSyntaxEval = pub type FnCustomSyntaxEval = dyn Fn(&mut EvalContext, &[Expression]) -> RhaiResult + Send + Sync;
dyn Fn(&mut EvalContext, &[Expression]) -> Result<Dynamic, Box<EvalAltResult>> + Send + Sync;
/// A general expression parsing trait object. /// A general expression parsing trait object.
#[cfg(not(feature = "sync"))] #[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]. /// This function is very low level. It evaluates an expression from an [`AST`][crate::AST].
#[inline(always)] #[inline(always)]
pub fn eval_expression_tree( pub fn eval_expression_tree(&mut self, expr: &Expression) -> RhaiResult {
&mut self,
expr: &Expression,
) -> Result<Dynamic, Box<EvalAltResult>> {
self.engine.eval_expr( self.engine.eval_expr(
self.scope, self.scope,
self.mods, self.mods,
@ -113,9 +107,7 @@ impl Engine {
&mut self, &mut self,
keywords: &[S], keywords: &[S],
new_vars: isize, new_vars: isize,
func: impl Fn(&mut EvalContext, &[Expression]) -> Result<Dynamic, Box<EvalAltResult>> func: impl Fn(&mut EvalContext, &[Expression]) -> RhaiResult + SendSync + 'static,
+ SendSync
+ 'static,
) -> Result<&mut Self, ParseError> { ) -> Result<&mut Self, ParseError> {
let keywords = keywords.as_ref(); let keywords = keywords.as_ref();
@ -234,9 +226,7 @@ impl Engine {
+ SendSync + SendSync
+ 'static, + 'static,
new_vars: isize, new_vars: isize,
func: impl Fn(&mut EvalContext, &[Expression]) -> Result<Dynamic, Box<EvalAltResult>> func: impl Fn(&mut EvalContext, &[Expression]) -> RhaiResult + SendSync + 'static,
+ SendSync
+ 'static,
) -> &mut Self { ) -> &mut Self {
let syntax = CustomSyntax { let syntax = CustomSyntax {
parse: Box::new(parse), parse: Box::new(parse),

View File

@ -1,12 +1,9 @@
use rhai::{Dynamic, Engine, EvalAltResult, NativeCallContext, INT}; use rhai::{Dynamic, Engine, EvalAltResult, NativeCallContext, RhaiResult, INT};
use std::any::TypeId; use std::any::TypeId;
#[test] #[test]
fn test_native_context() -> Result<(), Box<EvalAltResult>> { fn test_native_context() -> Result<(), Box<EvalAltResult>> {
fn add_double( fn add_double(context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
context: NativeCallContext,
args: &mut [&mut Dynamic],
) -> Result<Dynamic, Box<EvalAltResult>> {
let x = args[0].as_int().unwrap(); let x = args[0].as_int().unwrap();
let y = args[1].as_int().unwrap(); let y = args[1].as_int().unwrap();
Ok(format!("{}_{}", context.fn_name(), x + 2 * y).into()) Ok(format!("{}_{}", context.fn_name(), x + 2 * y).into())

View File

@ -18,7 +18,7 @@ mod test {
#[rhai_fn(get = "foo", return_raw)] #[rhai_fn(get = "foo", return_raw)]
#[inline(always)] #[inline(always)]
pub fn foo(array: &mut Array) -> Result<Dynamic, Box<EvalAltResult>> { pub fn foo(array: &mut Array) -> RhaiResult {
Ok(array[0].clone()) Ok(array[0].clone())
} }
} }