From a82f0fc738c6d3122b6ce3e404d9b3caaa17bf32 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 22 Mar 2021 11:18:09 +0800 Subject: [PATCH] Allow non-Dynamic in return_raw. --- CHANGELOG.md | 4 +- codegen/src/function.rs | 33 +------ codegen/src/test/function.rs | 4 +- .../ui_tests/export_fn_raw_noreturn.stderr | 2 +- codegen/ui_tests/export_fn_raw_return.stderr | 13 ++- .../ui_tests/export_mod_raw_noreturn.stderr | 2 +- codegen/ui_tests/export_mod_raw_return.stderr | 14 ++- .../rhai_fn_non_clonable_return.stderr | 2 +- .../rhai_mod_non_clonable_return.stderr | 2 +- src/ast.rs | 2 +- src/dynamic.rs | 55 +++++------ src/engine.rs | 6 -- src/engine_api.rs | 5 +- src/fn_builtin.rs | 2 +- src/fn_func.rs | 5 +- src/lib.rs | 6 +- src/packages/arithmetic.rs | 88 ++++++++--------- src/packages/array_basic.rs | 94 ++++++++----------- src/packages/map_basic.rs | 16 ++-- src/packages/math_basic.rs | 92 ++++++++---------- src/packages/string_more.rs | 8 +- src/packages/time_basic.rs | 35 ++++--- src/unsafe.rs | 6 +- 23 files changed, 214 insertions(+), 282 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d0dd3b4..9055d3df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,14 @@ Breaking changes * The traits `RegisterFn` and `RegisterResultFn` are removed. `Engine::register_fn` and `Engine::register_result_fn` are now implemented directly on `Engine`. * `FnPtr::call_dynamic` now takes `&NativeCallContext` instead of consuming it. * All `Module::set_fn_XXX` methods are removed, in favor of `Module::set_native_fn`. +* `Array::reduce` and `Array::reduce_rev` now take a `Dynamic` as initial value instead of a function pointer. * `protected`, `super` are now reserved keywords. Enhancements ------------ -* `Engine::register_result_fn` no longer requires the successful return type to be `Dynamic`. It can now be any type. +* `Engine::register_result_fn` no longer requires the successful return type to be `Dynamic`. It can now be any clonable type. +* `#[rhai_fn(return_raw)]` can now return `Result>` where `T` is any clonable type instead of `Result>`. Version 0.19.14 diff --git a/codegen/src/function.rs b/codegen/src/function.rs index e1b23264..f69ed3cd 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -279,7 +279,6 @@ pub struct ExportedFn { signature: syn::Signature, visibility: syn::Visibility, pass_context: bool, - return_dynamic: bool, mut_receiver: bool, params: ExportedFnParams, } @@ -290,10 +289,6 @@ impl Parse for ExportedFn { let entire_span = fn_all.span(); let str_type_path = syn::parse2::(quote! { str }).unwrap(); - let dynamic_type_path1 = syn::parse2::(quote! { Dynamic }).unwrap(); - let dynamic_type_path2 = syn::parse2::(quote! { rhai::Dynamic }).unwrap(); - let mut return_dynamic = false; - let context_type_path1 = syn::parse2::(quote! { NativeCallContext }).unwrap(); let context_type_path2 = syn::parse2::(quote! { rhai::NativeCallContext }).unwrap(); @@ -400,11 +395,6 @@ impl Parse for ExportedFn { "Rhai functions cannot return references", )) } - syn::Type::Path(p) - if p.path == dynamic_type_path1 || p.path == dynamic_type_path2 => - { - return_dynamic = true - } _ => {} } } @@ -413,7 +403,6 @@ impl Parse for ExportedFn { signature: fn_all.sig, visibility, pass_context, - return_dynamic, mut_receiver, params: Default::default(), }) @@ -520,7 +509,7 @@ impl ExportedFn { if params.return_raw.is_some() && self.return_type().is_none() { return Err(syn::Error::new( params.return_raw.unwrap(), - "functions marked with 'return_raw' must return Result>", + "functions marked with 'return_raw' must return Result>", )); } @@ -656,13 +645,7 @@ impl ExportedFn { if self.params.return_raw.is_some() { quote_spanned! { return_span => pub #dynamic_signature { - #name(#(#arguments),*) - } - } - } else if self.return_dynamic { - quote_spanned! { return_span => - pub #dynamic_signature { - Ok(#name(#(#arguments),*)) + #name(#(#arguments),*).map(Dynamic::from) } } } else { @@ -890,18 +873,12 @@ impl ExportedFn { .map(|r| r.span()) .unwrap_or_else(|| proc_macro2::Span::call_site()); let return_expr = if !self.params.return_raw.is_some() { - if self.return_dynamic { - quote_spanned! { return_span => - Ok(#sig_name(#(#unpack_exprs),*)) - } - } else { - quote_spanned! { return_span => - Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*))) - } + quote_spanned! { return_span => + Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*))) } } else { quote_spanned! { return_span => - #sig_name(#(#unpack_exprs),*) + #sig_name(#(#unpack_exprs),*).map(Dynamic::from) } }; diff --git a/codegen/src/test/function.rs b/codegen/src/test/function.rs index 9a25b68a..25a0886a 100644 --- a/codegen/src/test/function.rs +++ b/codegen/src/test/function.rs @@ -447,7 +447,7 @@ mod generate_tests { fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult { debug_assert_eq!(args.len(), 0usize, "wrong arg count: {} != {}", args.len(), 0usize); - Ok(return_dynamic()) + Ok(Dynamic::from(return_dynamic())) } fn is_method_call(&self) -> bool { false } @@ -477,7 +477,7 @@ mod generate_tests { } #[allow(unused)] pub fn dynamic_result_fn() -> Result > { - Ok(return_dynamic()) + Ok(Dynamic::from(return_dynamic())) } } }; diff --git a/codegen/ui_tests/export_fn_raw_noreturn.stderr b/codegen/ui_tests/export_fn_raw_noreturn.stderr index d4a992c0..51df546a 100644 --- a/codegen/ui_tests/export_fn_raw_noreturn.stderr +++ b/codegen/ui_tests/export_fn_raw_noreturn.stderr @@ -1,4 +1,4 @@ -error: functions marked with 'return_raw' must return Result> +error: functions marked with 'return_raw' must return Result> --> $DIR/export_fn_raw_noreturn.rs:9:13 | 9 | #[export_fn(return_raw)] diff --git a/codegen/ui_tests/export_fn_raw_return.stderr b/codegen/ui_tests/export_fn_raw_return.stderr index 65ebcd8b..3dc04fa8 100644 --- a/codegen/ui_tests/export_fn_raw_return.stderr +++ b/codegen/ui_tests/export_fn_raw_return.stderr @@ -1,10 +1,9 @@ -error[E0308]: mismatched types - --> $DIR/export_fn_raw_return.rs:10:8 +error[E0599]: the method `map` exists for type `bool`, but its trait bounds were not satisfied + --> $DIR/export_fn_raw_return.rs:10:33 | -9 | #[export_fn(return_raw)] - | ------------------------ expected `Result>` because of return type 10 | pub fn test_fn(input: Point) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `bool` + | ^^^^ method cannot be called on `bool` due to unsatisfied trait bounds | - = note: expected enum `Result>` - found type `bool` + = note: the following trait bounds were not satisfied: + `bool: std::iter::Iterator` + which is required by `&mut bool: std::iter::Iterator` diff --git a/codegen/ui_tests/export_mod_raw_noreturn.stderr b/codegen/ui_tests/export_mod_raw_noreturn.stderr index d59be0f8..71945f4a 100644 --- a/codegen/ui_tests/export_mod_raw_noreturn.stderr +++ b/codegen/ui_tests/export_mod_raw_noreturn.stderr @@ -1,4 +1,4 @@ -error: functions marked with 'return_raw' must return Result> +error: functions marked with 'return_raw' must return Result> --> $DIR/export_mod_raw_noreturn.rs:11:11 | 11 | #[rhai_fn(return_raw)] diff --git a/codegen/ui_tests/export_mod_raw_return.stderr b/codegen/ui_tests/export_mod_raw_return.stderr index 2b194c02..d62b9d94 100644 --- a/codegen/ui_tests/export_mod_raw_return.stderr +++ b/codegen/ui_tests/export_mod_raw_return.stderr @@ -1,11 +1,9 @@ -error[E0308]: mismatched types - --> $DIR/export_mod_raw_return.rs:12:8 +error[E0599]: the method `map` exists for type `bool`, but its trait bounds were not satisfied + --> $DIR/export_mod_raw_return.rs:12:33 | -9 | #[export_module] - | ---------------- expected `Result>` because of return type -... 12 | pub fn test_fn(input: Point) -> bool { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `bool` + | ^^^^ method cannot be called on `bool` due to unsatisfied trait bounds | - = note: expected enum `Result>` - found type `bool` + = note: the following trait bounds were not satisfied: + `bool: std::iter::Iterator` + which is required by `&mut bool: std::iter::Iterator` diff --git a/codegen/ui_tests/rhai_fn_non_clonable_return.stderr b/codegen/ui_tests/rhai_fn_non_clonable_return.stderr index 73d02b28..b9016a12 100644 --- a/codegen/ui_tests/rhai_fn_non_clonable_return.stderr +++ b/codegen/ui_tests/rhai_fn_non_clonable_return.stderr @@ -6,5 +6,5 @@ error[E0277]: the trait bound `NonClonable: Clone` is not satisfied | ::: $WORKSPACE/src/dynamic.rs | - | pub fn from(value: T) -> Self { + | pub fn from(mut value: T) -> Self { | ----- required by this bound in `rhai::Dynamic::from` diff --git a/codegen/ui_tests/rhai_mod_non_clonable_return.stderr b/codegen/ui_tests/rhai_mod_non_clonable_return.stderr index e7860394..900efa16 100644 --- a/codegen/ui_tests/rhai_mod_non_clonable_return.stderr +++ b/codegen/ui_tests/rhai_mod_non_clonable_return.stderr @@ -6,5 +6,5 @@ error[E0277]: the trait bound `NonClonable: Clone` is not satisfied | ::: $WORKSPACE/src/dynamic.rs | - | pub fn from(value: T) -> Self { + | pub fn from(mut value: T) -> Self { | ----- required by this bound in `rhai::Dynamic::from` diff --git a/src/ast.rs b/src/ast.rs index 39a5796a..5ca155a4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1303,7 +1303,7 @@ pub struct OpAssignment { /// /// Two separate hashes are pre-calculated because of the following pattern: /// -/// ```,ignore +/// ```ignore /// func(a, b, c); // Native: func(a, b, c) - 3 parameters /// // Script: func(a, b, c) - 3 parameters /// diff --git a/src/dynamic.rs b/src/dynamic.rs index b6bb5e71..4b52e89e 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -833,9 +833,13 @@ impl Dynamic { /// assert_eq!(new_result.to_string(), "hello"); /// ``` #[inline(always)] - pub fn from(value: T) -> Self { + pub fn from(mut value: T) -> Self { // Coded this way in order to maximally leverage potentials for dead-code removal. + if TypeId::of::() == TypeId::of::() { + return unsafe_try_cast::<_, Dynamic>(value).ok().unwrap(); + } + if TypeId::of::() == TypeId::of::() { return ::downcast_ref::(&value) .unwrap() @@ -884,46 +888,43 @@ impl Dynamic { return ().into(); } - let mut boxed = Box::new(value); - - boxed = match unsafe_cast_box::<_, Dynamic>(boxed) { - Ok(d) => return *d, - Err(val) => val, - }; - boxed = match unsafe_cast_box::<_, String>(boxed) { - Ok(s) => return (*s).into(), + value = match unsafe_try_cast::<_, String>(value) { + Ok(s) => return (s).into(), Err(val) => val, }; #[cfg(not(feature = "no_index"))] { - boxed = match unsafe_cast_box::<_, Array>(boxed) { - Ok(array) => return (*array).into(), + value = match unsafe_try_cast::<_, Array>(value) { + Ok(array) => return (array).into(), Err(val) => val, }; } #[cfg(not(feature = "no_object"))] { - boxed = match unsafe_cast_box::<_, Map>(boxed) { - Ok(map) => return (*map).into(), + value = match unsafe_try_cast::<_, Map>(value) { + Ok(map) => return (map).into(), Err(val) => val, } } - boxed = match unsafe_cast_box::<_, FnPtr>(boxed) { - Ok(fn_ptr) => return (*fn_ptr).into(), + value = match unsafe_try_cast::<_, FnPtr>(value) { + Ok(fn_ptr) => return (fn_ptr).into(), Err(val) => val, }; #[cfg(not(feature = "no_std"))] { - boxed = match unsafe_cast_box::<_, Instant>(boxed) { - Ok(timestamp) => return (*timestamp).into(), + value = match unsafe_try_cast::<_, Instant>(value) { + Ok(timestamp) => return (timestamp).into(), Err(val) => val, } } - Self(Union::Variant(Box::new(boxed), AccessMode::ReadWrite)) + Self(Union::Variant( + Box::new(Box::new(value)), + AccessMode::ReadWrite, + )) } /// Turn the [`Dynamic`] value into a shared [`Dynamic`] value backed by an /// [`Rc`][std::rc::Rc]`<`[`RefCell`][std::cell::RefCell]`<`[`Dynamic`]`>>` or @@ -986,12 +987,12 @@ impl Dynamic { } if TypeId::of::() == TypeId::of::() { - return unsafe_cast_box::<_, T>(Box::new(self)).ok().map(|v| *v); + return unsafe_try_cast::<_, T>(self).ok(); } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Int(value, _) => unsafe_try_cast(value), + Union::Int(value, _) => unsafe_try_cast(value).ok(), _ => None, }; } @@ -999,7 +1000,7 @@ impl Dynamic { #[cfg(not(feature = "no_float"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Float(value, _) => unsafe_try_cast(*value), + Union::Float(value, _) => unsafe_try_cast(*value).ok(), _ => None, }; } @@ -1007,35 +1008,35 @@ impl Dynamic { #[cfg(feature = "decimal")] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Decimal(value, _) => unsafe_try_cast(*value), + Union::Decimal(value, _) => unsafe_try_cast(*value).ok(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Bool(value, _) => unsafe_try_cast(value), + Union::Bool(value, _) => unsafe_try_cast(value).ok(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(value, _) => unsafe_try_cast(value), + Union::Str(value, _) => unsafe_try_cast(value).ok(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(value, _) => unsafe_try_cast(value.into_owned()), + Union::Str(value, _) => unsafe_try_cast(value.into_owned()).ok(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Char(value, _) => unsafe_try_cast(value), + Union::Char(value, _) => unsafe_try_cast(value).ok(), _ => None, }; } @@ -1073,7 +1074,7 @@ impl Dynamic { if TypeId::of::() == TypeId::of::<()>() { return match self.0 { - Union::Unit(value, _) => unsafe_try_cast(value), + Union::Unit(value, _) => unsafe_try_cast(value).ok(), _ => None, }; } diff --git a/src/engine.rs b/src/engine.rs index 4061431c..b2a3dcfb 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1047,12 +1047,6 @@ impl Engine { let val = scope.get_mut_by_index(index); - // Check for data race - probably not necessary because the only place it should conflict is - // in a method call when the object variable is also used as a parameter. - // if cfg!(not(feature = "no_closure")) && val.is_locked() { - // return EvalAltResult::ErrorDataRace(name.into(), *pos).into(); - // } - Ok((val.into(), *pos)) } diff --git a/src/engine_api.rs b/src/engine_api.rs index 6900a268..1f80b747 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -1885,9 +1885,8 @@ impl Engine { .ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::NONE))?; // Check for data race. - if cfg!(not(feature = "no_closure")) { - crate::fn_call::ensure_no_data_race(name, args, false)?; - } + #[cfg(not(feature = "no_closure"))] + crate::fn_call::ensure_no_data_race(name, args, false)?; self.call_script_fn( scope, diff --git a/src/fn_builtin.rs b/src/fn_builtin.rs index c592bb0e..828de6fb 100644 --- a/src/fn_builtin.rs +++ b/src/fn_builtin.rs @@ -109,7 +109,7 @@ pub fn get_builtin_binary_op_fn( return Some(|_, args| { let x = args[0].$xx().unwrap() as $base; let y = args[1].$yy().unwrap() as $base; - $func(x, y) + $func(x, y).map(Into::::into) }) }; (from $base:ty => $xx:ident $op:tt $yy:ident) => { diff --git a/src/fn_func.rs b/src/fn_func.rs index a9576989..93c036ff 100644 --- a/src/fn_func.rs +++ b/src/fn_func.rs @@ -98,10 +98,7 @@ macro_rules! def_anonymous_fn { #[inline(always)] fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output { let fn_name = entry_point.to_string(); - - Box::new(move |$($par: $par),*| { - self.call_fn(&mut Scope::new(), &ast, &fn_name, ($($par,)*)) - }) + Box::new(move |$($par),*| self.call_fn(&mut Scope::new(), &ast, &fn_name, ($($par,)*))) } #[inline(always)] diff --git a/src/lib.rs b/src/lib.rs index 0b34b4af..982f3e01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ //! //! ## Contents of `my_script.rhai` //! -//! ```,ignore +//! ```ignore //! /// Brute force factorial function //! fn factorial(x) { //! if x == 1 { return 1; } @@ -24,7 +24,7 @@ //! //! ## The Rust part //! -//! ```,no_run +//! ```no_run //! use rhai::{Engine, EvalAltResult}; //! //! fn main() -> Result<(), Box> @@ -88,7 +88,7 @@ mod token; mod r#unsafe; mod utils; -type RhaiResult = Result>; +type RhaiResult = stdlib::result::Result>; /// The system integer type. It is defined as [`i64`]. /// diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index 0c96a6af..1844dc66 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -24,91 +24,91 @@ macro_rules! gen_arithmetic_functions { #[export_module] pub mod functions { #[rhai_fn(name = "+", return_raw)] - pub fn add(x: $arg_type, y: $arg_type) -> Result> { + pub fn add(x: $arg_type, y: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_add(y).ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))).map(Dynamic::from) + x.checked_add(y).ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))) } else { - Ok(Dynamic::from(x + y)) + Ok(x + y) } } #[rhai_fn(name = "-", return_raw)] - pub fn subtract(x: $arg_type, y: $arg_type) -> Result> { + pub fn subtract(x: $arg_type, y: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_sub(y).ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))).map(Dynamic::from) + x.checked_sub(y).ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))) } else { - Ok(Dynamic::from(x - y)) + Ok(x - y) } } #[rhai_fn(name = "*", return_raw)] - pub fn multiply(x: $arg_type, y: $arg_type) -> Result> { + pub fn multiply(x: $arg_type, y: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_mul(y).ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))).map(Dynamic::from) + x.checked_mul(y).ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))) } else { - Ok(Dynamic::from(x * y)) + Ok(x * y) } } #[rhai_fn(name = "/", return_raw)] - pub fn divide(x: $arg_type, y: $arg_type) -> Result> { + pub fn divide(x: $arg_type, y: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { // Detect division by zero if y == 0 { Err(make_err(format!("Division by zero: {} / {}", x, y))) } else { - x.checked_div(y).ok_or_else(|| make_err(format!("Division overflow: {} / {}", x, y))).map(Dynamic::from) + x.checked_div(y).ok_or_else(|| make_err(format!("Division overflow: {} / {}", x, y))) } } else { - Ok(Dynamic::from(x / y)) + Ok(x / y) } } #[rhai_fn(name = "%", return_raw)] - pub fn modulo(x: $arg_type, y: $arg_type) -> Result> { + pub fn modulo(x: $arg_type, y: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_rem(y).ok_or_else(|| make_err(format!("Modulo division by zero or overflow: {} % {}", x, y))).map(Dynamic::from) + x.checked_rem(y).ok_or_else(|| make_err(format!("Modulo division by zero or overflow: {} % {}", x, y))) } else { - Ok(Dynamic::from(x % y)) + Ok(x % y) } } #[rhai_fn(name = "**", return_raw)] - pub fn power(x: INT, y: INT) -> Result> { + pub fn power(x: $arg_type, y: INT) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { Err(make_err(format!("Integer raised to too large an index: {} ~ {}", x, y))) } else if y < 0 { Err(make_err(format!("Integer raised to a negative index: {} ~ {}", x, y))) } else { - x.checked_pow(y as u32).ok_or_else(|| make_err(format!("Power overflow: {} ~ {}", x, y))).map(Dynamic::from) + x.checked_pow(y as u32).ok_or_else(|| make_err(format!("Power overflow: {} ~ {}", x, y))) } } else { - Ok(Dynamic::from(x.pow(y as u32))) + Ok(x.pow(y as u32)) } } #[rhai_fn(name = "<<", return_raw)] - pub fn shift_left(x: $arg_type, y: INT) -> Result> { + pub fn shift_left(x: $arg_type, y: INT) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { Err(make_err(format!("Left-shift by too many bits: {} << {}", x, y))) } else if y < 0 { Err(make_err(format!("Left-shift by a negative number: {} << {}", x, y))) } else { - x.checked_shl(y as u32).ok_or_else(|| make_err(format!("Left-shift by too many bits: {} << {}", x, y))).map(Dynamic::from) + x.checked_shl(y as u32).ok_or_else(|| make_err(format!("Left-shift by too many bits: {} << {}", x, y))) } } else { - Ok(Dynamic::from(x << y)) + Ok(x << y) } } #[rhai_fn(name = ">>", return_raw)] - pub fn shift_right(x: $arg_type, y: INT) -> Result> { + pub fn shift_right(x: $arg_type, y: INT) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) { Err(make_err(format!("Right-shift by too many bits: {} >> {}", x, y))) } else if y < 0 { Err(make_err(format!("Right-shift by a negative number: {} >> {}", x, y))) } else { - x.checked_shr(y as u32).ok_or_else(|| make_err(format!("Right-shift by too many bits: {} >> {}", x, y))).map(Dynamic::from) + x.checked_shr(y as u32).ok_or_else(|| make_err(format!("Right-shift by too many bits: {} >> {}", x, y))) } } else { - Ok(Dynamic::from(x >> y)) + Ok(x >> y) } } #[rhai_fn(name = "&")] @@ -136,11 +136,11 @@ macro_rules! gen_signed_functions { #[export_module] pub mod functions { #[rhai_fn(name = "-", return_raw)] - pub fn neg(x: $arg_type) -> Result> { + pub fn neg(x: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_neg().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from) + x.checked_neg().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))) } else { - Ok(Dynamic::from(-x)) + Ok(-x) } } #[rhai_fn(name = "+")] @@ -148,11 +148,11 @@ macro_rules! gen_signed_functions { x } #[rhai_fn(return_raw)] - pub fn abs(x: $arg_type) -> Result> { + pub fn abs(x: $arg_type) -> Result<$arg_type, Box> { if cfg!(not(feature = "unchecked")) { - x.checked_abs().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from) + x.checked_abs().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))) } else { - Ok(Dynamic::from(x.abs())) + Ok(x.abs()) } } pub fn sign(x: $arg_type) -> INT { @@ -318,14 +318,14 @@ mod f32_functions { } } #[rhai_fn(name = "**", return_raw)] - pub fn pow_f_i(x: f32, y: INT) -> Result> { + pub fn pow_f_i(x: f32, y: INT) -> Result> { if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) { Err(make_err(format!( "Number raised to too large an index: {} ~ {}", x, y ))) } else { - Ok(Dynamic::from(x.powi(y as i32))) + Ok(x.powi(y as i32)) } } } @@ -423,14 +423,14 @@ mod f64_functions { } } #[rhai_fn(name = "**", return_raw)] - pub fn pow_f_i(x: FLOAT, y: INT) -> Result> { + pub fn pow_f_i(x: FLOAT, y: INT) -> Result> { if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) { Err(make_err(format!( "Number raised to too large an index: {} ~ {}", x, y ))) } else { - Ok(x.powi(y as i32).into()) + Ok(x.powi(y as i32)) } } } @@ -441,37 +441,37 @@ pub mod decimal_functions { use rust_decimal::{prelude::Zero, Decimal}; #[rhai_fn(skip, return_raw)] - pub fn add(x: Decimal, y: Decimal) -> Result> { + pub fn add(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_add(y) .ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))) .map(Into::::into) } else { - Ok(Dynamic::from(x + y)) + Ok(x + y) } } #[rhai_fn(skip, return_raw)] - pub fn subtract(x: Decimal, y: Decimal) -> Result> { + pub fn subtract(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_sub(y) .ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))) .map(Into::::into) } else { - Ok(Dynamic::from(x - y)) + Ok(x - y) } } #[rhai_fn(skip, return_raw)] - pub fn multiply(x: Decimal, y: Decimal) -> Result> { + pub fn multiply(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_mul(y) .ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))) .map(Into::::into) } else { - Ok(Dynamic::from(x * y)) + Ok(x * y) } } #[rhai_fn(skip, return_raw)] - pub fn divide(x: Decimal, y: Decimal) -> Result> { + pub fn divide(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { // Detect division by zero if y == Decimal::zero() { @@ -482,11 +482,11 @@ pub mod decimal_functions { .map(Into::::into) } } else { - Ok(Dynamic::from(x / y)) + Ok(x / y) } } #[rhai_fn(skip, return_raw)] - pub fn modulo(x: Decimal, y: Decimal) -> Result> { + pub fn modulo(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_rem(y) .ok_or_else(|| { @@ -497,7 +497,7 @@ pub mod decimal_functions { }) .map(Into::::into) } else { - Ok(Dynamic::from(x % y)) + Ok(x % y) } } #[rhai_fn(name = "-")] diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 5244c46d..0c4701a7 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -47,7 +47,7 @@ mod array_functions { array: &mut Array, len: INT, item: Dynamic, - ) -> Result> { + ) -> Result<(), Box> { // Check if array will be over max size limit #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_array_size() > 0 @@ -62,7 +62,7 @@ mod array_functions { array.resize(len as usize, item); } - Ok(Dynamic::UNIT) + Ok(()) } pub fn pop(array: &mut Array) -> Dynamic { array.pop().unwrap_or_else(|| ().into()) @@ -169,7 +169,7 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, mapper: FnPtr, - ) -> Result> { + ) -> Result> { let mut ar = Array::with_capacity(max(TYPICAL_ARRAY_SIZE, array.len())); for (i, item) in array.iter().enumerate() { @@ -195,14 +195,14 @@ mod array_functions { ); } - Ok(ar.into()) + Ok(ar) } #[rhai_fn(return_raw, pure)] pub fn filter( ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { let mut ar = Array::with_capacity(max(TYPICAL_ARRAY_SIZE, array.len())); for (i, item) in array.iter().enumerate() { @@ -231,14 +231,14 @@ mod array_functions { } } - Ok(ar.into()) + Ok(ar) } #[rhai_fn(return_raw, pure)] pub fn contains( ctx: NativeCallContext, array: &mut Array, value: Dynamic, - ) -> Result> { + ) -> Result> { for item in array.iter_mut() { if ctx .call_fn_dynamic_raw(OP_EQUALS, true, &mut [item, &mut value.clone()]) @@ -258,18 +258,18 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok(Dynamic::TRUE); + return Ok(true); } } - Ok(Dynamic::FALSE) + Ok(false) } #[rhai_fn(return_raw, pure)] pub fn index_of( ctx: NativeCallContext, array: &mut Array, value: Dynamic, - ) -> Result> { + ) -> Result> { for (i, item) in array.iter_mut().enumerate() { if ctx .call_fn_dynamic_raw(OP_EQUALS, true, &mut [item, &mut value.clone()]) @@ -289,18 +289,18 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok((i as INT).into()); + return Ok(i as INT); } } - Ok((-1 as INT).into()) + Ok(-1 as INT) } #[rhai_fn(name = "index_of", return_raw, pure)] pub fn index_of_filter( ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { for (i, item) in array.iter().enumerate() { if filter .call_dynamic(&ctx, None, [item.clone()]) @@ -323,18 +323,18 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok((i as INT).into()); + return Ok(i as INT); } } - Ok((-1 as INT).into()) + Ok(-1 as INT) } #[rhai_fn(return_raw, pure)] pub fn some( ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { for (i, item) in array.iter().enumerate() { if filter .call_dynamic(&ctx, None, [item.clone()]) @@ -357,18 +357,18 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok(true.into()); + return Ok(true); } } - Ok(false.into()) + Ok(false) } #[rhai_fn(return_raw, pure)] pub fn all( ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { for (i, item) in array.iter().enumerate() { if !filter .call_dynamic(&ctx, None, [item.clone()]) @@ -391,11 +391,11 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok(false.into()); + return Ok(false); } } - Ok(true.into()) + Ok(true) } #[rhai_fn(return_raw, pure)] pub fn reduce( @@ -403,7 +403,7 @@ mod array_functions { array: &mut Array, reducer: FnPtr, ) -> Result> { - let mut result: Dynamic = Dynamic::UNIT; + let mut result = Dynamic::UNIT; for (i, item) in array.iter().enumerate() { result = reducer @@ -433,16 +433,9 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, reducer: FnPtr, - initial: FnPtr, + initial: Dynamic, ) -> Result> { - let mut result = initial.call_dynamic(&ctx, None, []).map_err(|err| { - Box::new(EvalAltResult::ErrorInFunctionCall( - "reduce".to_string(), - ctx.source().unwrap_or("").to_string(), - err, - Position::NONE, - )) - })?; + let mut result = initial; for (i, item) in array.iter().enumerate() { result = reducer @@ -473,7 +466,7 @@ mod array_functions { array: &mut Array, reducer: FnPtr, ) -> Result> { - let mut result: Dynamic = Dynamic::UNIT; + let mut result = Dynamic::UNIT; for (i, item) in array.iter().enumerate().rev() { result = reducer @@ -503,16 +496,9 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, reducer: FnPtr, - initial: FnPtr, + initial: Dynamic, ) -> Result> { - let mut result = initial.call_dynamic(&ctx, None, []).map_err(|err| { - Box::new(EvalAltResult::ErrorInFunctionCall( - "reduce_rev".to_string(), - ctx.source().unwrap_or("").to_string(), - err, - Position::NONE, - )) - })?; + let mut result = initial; for (i, item) in array.iter().enumerate().rev() { result = reducer @@ -542,7 +528,7 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, comparer: FnPtr, - ) -> Result> { + ) -> Result<(), Box> { array.sort_by(|x, y| { comparer .call_dynamic(&ctx, None, [x.clone(), y.clone()]) @@ -571,14 +557,14 @@ mod array_functions { }) }); - Ok(Dynamic::UNIT) + Ok(()) } #[rhai_fn(return_raw)] pub fn drain( ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { let mut drained = Array::with_capacity(max(TYPICAL_ARRAY_SIZE, array.len())); let mut i = array.len(); @@ -611,7 +597,7 @@ mod array_functions { } } - Ok(drained.into()) + Ok(drained) } #[rhai_fn(name = "drain")] pub fn drain_range(array: &mut Array, start: INT, len: INT) -> Array { @@ -638,7 +624,7 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, filter: FnPtr, - ) -> Result> { + ) -> Result> { let mut drained = Array::with_capacity(max(TYPICAL_ARRAY_SIZE, array.len())); let mut i = array.len(); @@ -671,7 +657,7 @@ mod array_functions { } } - Ok(drained.into()) + Ok(drained) } #[rhai_fn(name = "retain")] pub fn retain_range(array: &mut Array, start: INT, len: INT) -> Array { @@ -701,12 +687,12 @@ mod array_functions { ctx: NativeCallContext, array: &mut Array, mut array2: Array, - ) -> Result> { + ) -> Result> { if array.len() != array2.len() { - return Ok(false.into()); + return Ok(false); } if array.is_empty() { - return Ok(true.into()); + return Ok(true); } for (a1, a2) in array.iter_mut().zip(array2.iter_mut()) { @@ -728,18 +714,18 @@ mod array_functions { .as_bool() .unwrap_or(false) { - return Ok(Dynamic::FALSE); + return Ok(false); } } - Ok(Dynamic::TRUE) + Ok(true) } #[rhai_fn(name = "!=", return_raw, pure)] pub fn not_equals( ctx: NativeCallContext, array: &mut Array, array2: Array, - ) -> Result> { - equals(ctx, array, array2).map(|r| (!r.as_bool().unwrap()).into()) + ) -> Result> { + equals(ctx, array, array2).map(|r| !r) } } diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index 673b9be3..41212ec0 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -46,12 +46,12 @@ mod map_functions { ctx: NativeCallContext, map: &mut Map, mut map2: Map, - ) -> Result> { + ) -> Result> { if map.len() != map2.len() { - return Ok(false.into()); + return Ok(false); } if map.is_empty() { - return Ok(true.into()); + return Ok(true); } for (m1, v1) in map.iter_mut() { @@ -61,22 +61,22 @@ mod map_functions { .map(|v| v.as_bool().unwrap_or(false))?; if !equals { - return Ok(false.into()); + return Ok(false); } } else { - return Ok(false.into()); + return Ok(false); } } - Ok(true.into()) + Ok(true) } #[rhai_fn(name = "!=", return_raw, pure)] pub fn not_equals( ctx: NativeCallContext, map: &mut Map, map2: Map, - ) -> Result> { - equals(ctx, map, map2).map(|r| (!r.as_bool().unwrap()).into()) + ) -> Result> { + equals(ctx, map, map2).map(|r| !r) } #[cfg(not(feature = "no_index"))] diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index 9adb5725..86fef583 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -113,7 +113,7 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, { #[export_module] mod int_functions { #[rhai_fn(name = "parse_int", return_raw)] - pub fn parse_int_radix(s: &str, radix: INT) -> Result> { + pub fn parse_int_radix(s: &str, radix: INT) -> Result> { if radix < 2 || radix > 36 { return EvalAltResult::ErrorArithmetic( format!("Invalid radix: '{}'", radix), @@ -122,18 +122,16 @@ mod int_functions { .into(); } - INT::from_str_radix(s.trim(), radix as u32) - .map(Into::::into) - .map_err(|err| { - EvalAltResult::ErrorArithmetic( - format!("Error parsing integer number '{}': {}", s, err), - Position::NONE, - ) - .into() - }) + INT::from_str_radix(s.trim(), radix as u32).map_err(|err| { + EvalAltResult::ErrorArithmetic( + format!("Error parsing integer number '{}': {}", s, err), + Position::NONE, + ) + .into() + }) } #[rhai_fn(name = "parse_int", return_raw)] - pub fn parse_int(s: &str) -> Result> { + pub fn parse_int(s: &str) -> Result> { parse_int_radix(s, 10) } } @@ -261,7 +259,7 @@ mod float_functions { x.is_infinite() } #[rhai_fn(name = "to_int", return_raw)] - pub fn f32_to_int(x: f32) -> Result> { + pub fn f32_to_int(x: f32) -> Result> { if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f32) { EvalAltResult::ErrorArithmetic( format!("Integer overflow: to_int({})", x), @@ -269,11 +267,11 @@ mod float_functions { ) .into() } else { - Ok((x.trunc() as INT).into()) + Ok(x.trunc() as INT) } } #[rhai_fn(name = "to_int", return_raw)] - pub fn f64_to_int(x: f64) -> Result> { + pub fn f64_to_int(x: f64) -> Result> { if cfg!(not(feature = "unchecked")) && x > (MAX_INT as f64) { EvalAltResult::ErrorArithmetic( format!("Integer overflow: to_int({})", x), @@ -281,21 +279,18 @@ mod float_functions { ) .into() } else { - Ok((x.trunc() as INT).into()) + Ok(x.trunc() as INT) } } #[rhai_fn(return_raw)] - pub fn parse_float(s: &str) -> Result> { - s.trim() - .parse::() - .map(Into::::into) - .map_err(|err| { - EvalAltResult::ErrorArithmetic( - format!("Error parsing floating-point number '{}': {}", s, err), - Position::NONE, - ) - .into() - }) + pub fn parse_float(s: &str) -> Result> { + s.trim().parse::().map_err(|err| { + EvalAltResult::ErrorArithmetic( + format!("Error parsing floating-point number '{}': {}", s, err), + Position::NONE, + ) + .into() + }) } #[cfg(not(feature = "f32_float"))] pub mod f32_f64 { @@ -327,10 +322,10 @@ mod decimal_functions { x.round() } #[rhai_fn(name = "round", return_raw)] - pub fn round_dp(x: Decimal, dp: INT) -> Result> { + pub fn round_dp(x: Decimal, dp: INT) -> Result> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) { - return Ok(x.into()); + return Ok(x); } if dp < 0 { return Err(make_err(format!( @@ -340,13 +335,13 @@ mod decimal_functions { } } - Ok(x.round_dp(dp as u32).into()) + Ok(x.round_dp(dp as u32)) } #[rhai_fn(return_raw)] - pub fn round_up(x: Decimal, dp: INT) -> Result> { + pub fn round_up(x: Decimal, dp: INT) -> Result> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) { - return Ok(x.into()); + return Ok(x); } if dp < 0 { return Err(make_err(format!( @@ -356,16 +351,13 @@ mod decimal_functions { } } - Ok( - x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundUp) - .into(), - ) + Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundUp)) } #[rhai_fn(return_raw)] - pub fn round_down(x: Decimal, dp: INT) -> Result> { + pub fn round_down(x: Decimal, dp: INT) -> Result> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) { - return Ok(x.into()); + return Ok(x); } if dp < 0 { return Err(make_err(format!( @@ -375,16 +367,13 @@ mod decimal_functions { } } - Ok( - x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundDown) - .into(), - ) + Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundDown)) } #[rhai_fn(return_raw)] - pub fn round_half_up(x: Decimal, dp: INT) -> Result> { + pub fn round_half_up(x: Decimal, dp: INT) -> Result> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) { - return Ok(x.into()); + return Ok(x); } if dp < 0 { return Err(make_err(format!( @@ -394,16 +383,13 @@ mod decimal_functions { } } - Ok( - x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundHalfUp) - .into(), - ) + Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundHalfUp)) } #[rhai_fn(return_raw)] - pub fn round_half_down(x: Decimal, dp: INT) -> Result> { + pub fn round_half_down(x: Decimal, dp: INT) -> Result> { if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) { - return Ok(x.into()); + return Ok(x); } if dp < 0 { return Err(make_err(format!( @@ -413,10 +399,7 @@ mod decimal_functions { } } - Ok( - x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundHalfDown) - .into(), - ) + Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::RoundHalfDown)) } #[rhai_fn(name = "int", get = "int")] pub fn int(x: Decimal) -> Decimal { @@ -427,10 +410,9 @@ mod decimal_functions { x.fract() } #[rhai_fn(return_raw)] - pub fn parse_decimal(s: &str) -> Result> { + pub fn parse_decimal(s: &str) -> Result> { Decimal::from_str(s) .or_else(|_| Decimal::from_scientific(s)) - .map(Into::::into) .map_err(|err| { EvalAltResult::ErrorArithmetic( format!("Error parsing decimal number '{}': {}", s, err), diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index ce3d819e..3477c7c2 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -235,7 +235,7 @@ mod string_functions { string: &mut ImmutableString, len: INT, character: char, - ) -> Result> { + ) -> Result<(), Box> { // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { @@ -269,7 +269,7 @@ mod string_functions { } } - Ok(Dynamic::UNIT) + Ok(()) } #[rhai_fn(name = "pad", return_raw)] pub fn pad_with_string( @@ -277,7 +277,7 @@ mod string_functions { string: &mut ImmutableString, len: INT, padding: &str, - ) -> Result> { + ) -> Result<(), Box> { // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_string_size() > 0 && len as usize > _ctx.engine().max_string_size() { @@ -318,7 +318,7 @@ mod string_functions { } } - Ok(Dynamic::UNIT) + Ok(()) } #[cfg(not(feature = "no_index"))] diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index f8135929..b60d4f6a 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -143,28 +143,28 @@ mod time_functions { } #[rhai_fn(return_raw, name = "+")] - pub fn add(timestamp: Instant, seconds: FLOAT) -> Result> { - add_impl(timestamp, seconds).map(Into::::into) + pub fn add(timestamp: Instant, seconds: FLOAT) -> Result> { + add_impl(timestamp, seconds) } #[rhai_fn(return_raw, name = "+=")] pub fn add_assign( timestamp: &mut Instant, seconds: FLOAT, - ) -> Result> { + ) -> Result<(), Box> { *timestamp = add_impl(*timestamp, seconds)?; - Ok(Dynamic::UNIT) + Ok(()) } #[rhai_fn(return_raw, name = "-")] - pub fn subtract(timestamp: Instant, seconds: FLOAT) -> Result> { - subtract_impl(timestamp, seconds).map(Into::::into) + pub fn subtract(timestamp: Instant, seconds: FLOAT) -> Result> { + subtract_impl(timestamp, seconds) } #[rhai_fn(return_raw, name = "-=")] pub fn subtract_assign( timestamp: &mut Instant, seconds: FLOAT, - ) -> Result> { + ) -> Result<(), Box> { *timestamp = subtract_impl(*timestamp, seconds)?; - Ok(Dynamic::UNIT) + Ok(()) } } @@ -202,28 +202,25 @@ mod time_functions { } #[rhai_fn(return_raw, name = "+")] - pub fn add(timestamp: Instant, seconds: INT) -> Result> { - add_impl(timestamp, seconds).map(Into::::into) + pub fn add(timestamp: Instant, seconds: INT) -> Result> { + add_impl(timestamp, seconds) } #[rhai_fn(return_raw, name = "+=")] - pub fn add_assign( - timestamp: &mut Instant, - seconds: INT, - ) -> Result> { + pub fn add_assign(timestamp: &mut Instant, seconds: INT) -> Result<(), Box> { *timestamp = add_impl(*timestamp, seconds)?; - Ok(Dynamic::UNIT) + Ok(()) } #[rhai_fn(return_raw, name = "-")] - pub fn subtract(timestamp: Instant, seconds: INT) -> Result> { - subtract_impl(timestamp, seconds).map(Into::::into) + pub fn subtract(timestamp: Instant, seconds: INT) -> Result> { + subtract_impl(timestamp, seconds) } #[rhai_fn(return_raw, name = "-=")] pub fn subtract_assign( timestamp: &mut Instant, seconds: INT, - ) -> Result> { + ) -> Result<(), Box> { *timestamp = subtract_impl(*timestamp, seconds)?; - Ok(Dynamic::UNIT) + Ok(()) } #[rhai_fn(name = "==")] diff --git a/src/unsafe.rs b/src/unsafe.rs index 772eb35a..de7aa1bc 100644 --- a/src/unsafe.rs +++ b/src/unsafe.rs @@ -9,7 +9,7 @@ use crate::stdlib::{ /// Cast a type into another type. #[inline(always)] -pub fn unsafe_try_cast(a: A) -> Option { +pub fn unsafe_try_cast(a: A) -> Result { if TypeId::of::() == a.type_id() { // SAFETY: Just checked we have the right type. We explicitly forget the // value immediately after moving out, removing any chance of a destructor @@ -17,10 +17,10 @@ pub fn unsafe_try_cast(a: A) -> Option { unsafe { let ret: B = ptr::read(&a as *const _ as *const B); mem::forget(a); - Some(ret) + Ok(ret) } } else { - None + Err(a) } }