Deprecate RegisterFn and RegisterResultFn.

This commit is contained in:
Stephen Chung 2021-03-15 11:36:30 +08:00
parent 2f8a3c24c0
commit d0922adb5b
35 changed files with 235 additions and 206 deletions

View File

@ -4,6 +4,12 @@ Rhai Release Notes
Version 0.19.15 Version 0.19.15
=============== ===============
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.
Version 0.19.14 Version 0.19.14
=============== ===============

View File

@ -3,7 +3,7 @@
///! Test evaluating expressions ///! Test evaluating expressions
extern crate test; extern crate test;
use rhai::{Array, Engine, Map, RegisterFn, INT}; use rhai::{Array, Engine, Map, INT};
use test::Bencher; use test::Bencher;
#[bench] #[bench]

View File

@ -3,7 +3,7 @@
///! Test evaluating expressions ///! Test evaluating expressions
extern crate test; extern crate test;
use rhai::{Engine, OptimizationLevel, RegisterFn, Scope, INT}; use rhai::{Engine, OptimizationLevel, Scope, INT};
use test::Bencher; use test::Bencher;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -35,7 +35,7 @@
//! # Register a Rust Function with a Rhai `Module` //! # Register a Rust Function with a Rhai `Module`
//! //!
//! ``` //! ```
//! use rhai::{EvalAltResult, FLOAT, Module, RegisterFn}; //! use rhai::{EvalAltResult, FLOAT, Module};
//! use rhai::plugin::*; //! use rhai::plugin::*;
//! use rhai::module_resolvers::*; //! use rhai::module_resolvers::*;
//! //!
@ -65,7 +65,7 @@
//! # Register a Plugin Function with an `Engine` //! # Register a Plugin Function with an `Engine`
//! //!
//! ``` //! ```
//! use rhai::{EvalAltResult, FLOAT, Module, RegisterFn}; //! use rhai::{EvalAltResult, FLOAT, Module};
//! use rhai::plugin::*; //! use rhai::plugin::*;
//! use rhai::module_resolvers::*; //! use rhai::module_resolvers::*;
//! //!

View File

@ -1,6 +1,6 @@
use rhai::module_resolvers::*; use rhai::module_resolvers::*;
use rhai::plugin::*; use rhai::plugin::*;
use rhai::{Engine, EvalAltResult, Module, RegisterFn, FLOAT}; use rhai::{Engine, EvalAltResult, Module, FLOAT};
pub mod raw_fn { pub mod raw_fn {
use rhai::plugin::*; use rhai::plugin::*;

View File

@ -1,5 +1,5 @@
use rhai::module_resolvers::*; use rhai::module_resolvers::*;
use rhai::{Array, Engine, EvalAltResult, RegisterFn, FLOAT, INT}; use rhai::{Array, Engine, EvalAltResult, FLOAT, INT};
pub mod empty_module { pub mod empty_module {
use rhai::plugin::*; use rhai::plugin::*;

View File

@ -1,5 +1,5 @@
use rhai::module_resolvers::*; use rhai::module_resolvers::*;
use rhai::{Array, Engine, EvalAltResult, RegisterFn, FLOAT, INT}; use rhai::{Array, Engine, EvalAltResult, FLOAT, INT};
pub mod one_fn_module_nested_attr { pub mod one_fn_module_nested_attr {
use rhai::plugin::*; use rhai::plugin::*;

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct TestStruct { struct TestStruct {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct TestStruct { struct TestStruct {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
fn add(x: INT, y: INT) -> INT { fn add(x: INT, y: INT) -> INT {
x + y x + y

View File

@ -1,6 +1,6 @@
///! This example registers a variety of functions that operate on strings. ///! This example registers a variety of functions that operate on strings.
///! Remember to use `ImmutableString` or `&str` instead of `String` as parameters. ///! Remember to use `ImmutableString` or `&str` instead of `String` as parameters.
use rhai::{Engine, EvalAltResult, ImmutableString, RegisterFn, Scope, INT}; use rhai::{Engine, EvalAltResult, ImmutableString, Scope, INT};
use std::io::{stdin, stdout, Write}; use std::io::{stdin, stdout, Write};
/// Trim whitespace from a string. The original string argument is changed. /// Trim whitespace from a string. The original string argument is changed.

View File

@ -1,4 +1,4 @@
use rhai::{Engine, RegisterFn, INT}; use rhai::{Engine, INT};
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
use std::sync::Mutex; use std::sync::Mutex;

View File

@ -3,6 +3,7 @@
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::engine::{EvalContext, Imports, State}; use crate::engine::{EvalContext, Imports, State};
use crate::fn_native::{FnCallArgs, SendSync}; use crate::fn_native::{FnCallArgs, SendSync};
use crate::fn_register::RegisterNativeFunction;
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::stdlib::{ use crate::stdlib::{
any::{type_name, TypeId}, any::{type_name, TypeId},
@ -24,6 +25,68 @@ use crate::Map;
/// Engine public API /// Engine public API
impl Engine { impl Engine {
/// Register a custom function with the [`Engine`].
///
/// # Example
///
/// ```
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::Engine;
///
/// // Normal function
/// fn add(x: i64, y: i64) -> i64 {
/// x + y
/// }
///
/// let mut engine = Engine::new();
///
/// engine.register_fn("add", add);
///
/// assert_eq!(engine.eval::<i64>("add(40, 2)")?, 42);
///
/// // You can also register a closure.
/// engine.register_fn("sub", |x: i64, y: i64| x - y );
///
/// assert_eq!(engine.eval::<i64>("sub(44, 2)")?, 42);
/// # Ok(())
/// # }
/// ```
pub fn register_fn<A>(&mut self, name: &str, func: impl RegisterNativeFunction<A, ()>) -> &mut Self {
func.register_into(self, name);
self
}
/// Register a custom fallible function with the [`Engine`].
///
/// # Example
///
/// ```
/// use rhai::{Engine, Dynamic, EvalAltResult};
///
/// // Normal function
/// fn div(x: i64, y: i64) -> Result<Dynamic, Box<EvalAltResult>> {
/// if y == 0 {
/// // '.into()' automatically converts to 'Box<EvalAltResult::ErrorRuntime>'
/// Err("division by zero!".into())
/// } else {
/// Ok((x / y).into())
/// }
/// }
///
/// let mut engine = Engine::new();
///
/// engine.register_result_fn("div", div);
///
/// engine.eval::<i64>("div(42, 0)")
/// .expect_err("expecting division by zero error!");
/// ```
pub fn register_result_fn<A>(
&mut self,
name: &str,
func: impl RegisterNativeFunction<A, RhaiResult>,
) -> &mut Self {
func.register_into(self, name);
self
}
/// Register a function of the [`Engine`]. /// Register a function of the [`Engine`].
/// ///
/// # WARNING - Low Level API /// # WARNING - Low Level API
@ -76,7 +139,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -115,7 +178,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -177,7 +240,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -199,7 +262,7 @@ impl Engine {
name: &str, name: &str,
get_fn: impl Fn(&mut T) -> U + SendSync + 'static, get_fn: impl Fn(&mut T) -> U + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
use crate::{engine::make_getter, RegisterFn}; use crate::engine::make_getter;
self.register_fn(&make_getter(name), get_fn) self.register_fn(&make_getter(name), get_fn)
} }
/// Register a getter function for a member of a registered type with the [`Engine`]. /// Register a getter function for a member of a registered type with the [`Engine`].
@ -209,7 +272,7 @@ impl Engine {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn}; /// use rhai::{Engine, Dynamic, EvalAltResult};
/// ///
/// #[derive(Clone)] /// #[derive(Clone)]
/// struct TestStruct { /// struct TestStruct {
@ -246,7 +309,7 @@ impl Engine {
name: &str, name: &str,
get_fn: impl Fn(&mut T) -> RhaiResult + 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;
self.register_result_fn(&make_getter(name), get_fn) self.register_result_fn(&make_getter(name), get_fn)
} }
/// Register a setter function for a member of a registered type with the [`Engine`]. /// Register a setter function for a member of a registered type with the [`Engine`].
@ -266,7 +329,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -292,7 +355,7 @@ impl Engine {
name: &str, name: &str,
set_fn: impl Fn(&mut T, U) + SendSync + 'static, set_fn: impl Fn(&mut T, U) + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
use crate::{engine::make_setter, RegisterFn}; use crate::engine::make_setter;
self.register_fn(&make_setter(name), set_fn) self.register_fn(&make_setter(name), set_fn)
} }
/// Register a setter function for a member of a registered type with the [`Engine`]. /// Register a setter function for a member of a registered type with the [`Engine`].
@ -300,7 +363,7 @@ impl Engine {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn}; /// use rhai::{Engine, Dynamic, EvalAltResult};
/// ///
/// #[derive(Debug, Clone, Eq, PartialEq)] /// #[derive(Debug, Clone, Eq, PartialEq)]
/// struct TestStruct { /// struct TestStruct {
@ -341,7 +404,7 @@ impl Engine {
name: &str, name: &str,
set_fn: impl Fn(&mut T, U) -> Result<(), Box<EvalAltResult>> + SendSync + 'static, set_fn: impl Fn(&mut T, U) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
) -> &mut Self { ) -> &mut Self {
use crate::{engine::make_setter, RegisterResultFn}; use crate::engine::make_setter;
self.register_result_fn(&make_setter(name), move |obj: &mut T, value: U| { self.register_result_fn(&make_setter(name), move |obj: &mut T, value: U| {
set_fn(obj, value).map(Into::into) set_fn(obj, value).map(Into::into)
}) })
@ -369,7 +432,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -420,7 +483,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -457,8 +520,7 @@ impl Engine {
panic!("Cannot register indexer for strings."); panic!("Cannot register indexer for strings.");
} }
use crate::{engine::FN_IDX_GET, RegisterFn}; self.register_fn(crate::engine::FN_IDX_GET, get_fn)
self.register_fn(FN_IDX_GET, get_fn)
} }
/// Register an index getter for a custom type with the [`Engine`]. /// Register an index getter for a custom type with the [`Engine`].
/// ///
@ -472,7 +534,7 @@ impl Engine {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn}; /// use rhai::{Engine, Dynamic, EvalAltResult};
/// ///
/// #[derive(Clone)] /// #[derive(Clone)]
/// struct TestStruct { /// struct TestStruct {
@ -524,8 +586,7 @@ impl Engine {
panic!("Cannot register indexer for strings."); panic!("Cannot register indexer for strings.");
} }
use crate::{engine::FN_IDX_GET, RegisterResultFn}; self.register_result_fn(crate::engine::FN_IDX_GET, get_fn)
self.register_result_fn(FN_IDX_GET, get_fn)
} }
/// Register an index setter for a custom type with the [`Engine`]. /// Register an index setter for a custom type with the [`Engine`].
/// ///
@ -549,7 +610,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///
@ -589,8 +650,7 @@ impl Engine {
panic!("Cannot register indexer for strings."); panic!("Cannot register indexer for strings.");
} }
use crate::{engine::FN_IDX_SET, RegisterFn}; self.register_fn(crate::engine::FN_IDX_SET, set_fn)
self.register_fn(FN_IDX_SET, set_fn)
} }
/// Register an index setter for a custom type with the [`Engine`]. /// Register an index setter for a custom type with the [`Engine`].
/// ///
@ -602,7 +662,7 @@ impl Engine {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use rhai::{Engine, Dynamic, EvalAltResult, RegisterFn}; /// use rhai::{Engine, Dynamic, EvalAltResult};
/// ///
/// #[derive(Clone)] /// #[derive(Clone)]
/// struct TestStruct { /// struct TestStruct {
@ -661,10 +721,10 @@ impl Engine {
panic!("Cannot register indexer for strings."); panic!("Cannot register indexer for strings.");
} }
use crate::{engine::FN_IDX_SET, RegisterResultFn}; self.register_result_fn(
self.register_result_fn(FN_IDX_SET, move |obj: &mut T, index: X, value: U| { crate::engine::FN_IDX_SET,
set_fn(obj, index, value).map(Into::into) move |obj: &mut T, index: X, value: U| set_fn(obj, index, value).map(Into::into),
}) )
} }
/// Short-hand for register both index getter and setter functions for a custom type with the [`Engine`]. /// Short-hand for register both index getter and setter functions for a custom type with the [`Engine`].
/// ///
@ -691,7 +751,7 @@ impl Engine {
/// } /// }
/// ///
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///

View File

@ -250,7 +250,7 @@ impl Engine {
/// ///
/// ```rust /// ```rust
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> { /// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn}; /// use rhai::Engine;
/// ///
/// let mut engine = Engine::new(); /// let mut engine = Engine::new();
/// ///

View File

@ -49,7 +49,7 @@ pub use crate::stdlib::cell::RefCell as Locked;
pub use crate::stdlib::sync::RwLock as Locked; pub use crate::stdlib::sync::RwLock as Locked;
/// Context of a native Rust function call. /// Context of a native Rust function call.
#[derive(Debug, Copy, Clone)] #[derive(Debug)]
pub struct NativeCallContext<'a> { pub struct NativeCallContext<'a> {
engine: &'a Engine, engine: &'a Engine,
fn_name: &'a str, fn_name: &'a str,
@ -320,7 +320,7 @@ impl FnPtr {
#[inline(always)] #[inline(always)]
pub fn call_dynamic( pub fn call_dynamic(
&self, &self,
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]>,
) -> RhaiResult { ) -> RhaiResult {

View File

@ -4,72 +4,10 @@
use crate::dynamic::{DynamicWriteLock, Variant}; use crate::dynamic::{DynamicWriteLock, Variant};
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync}; use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
use crate::r#unsafe::unsafe_cast_box; use crate::r#unsafe::unsafe_try_cast;
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String}; use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String};
use crate::{Dynamic, Engine, FnAccess, FnNamespace, NativeCallContext, RhaiResult}; use crate::{Dynamic, Engine, FnAccess, FnNamespace, NativeCallContext, RhaiResult};
/// Trait to register custom functions with the [`Engine`].
pub trait RegisterFn<FN, ARGS, RET> {
/// Register a custom function with the [`Engine`].
///
/// # Example
///
/// ```
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
/// use rhai::{Engine, RegisterFn};
///
/// // Normal function
/// fn add(x: i64, y: i64) -> i64 {
/// x + y
/// }
///
/// let mut engine = Engine::new();
///
/// // You must use the trait rhai::RegisterFn to get this method.
/// engine.register_fn("add", add);
///
/// assert_eq!(engine.eval::<i64>("add(40, 2)")?, 42);
///
/// // You can also register a closure.
/// engine.register_fn("sub", |x: i64, y: i64| x - y );
///
/// assert_eq!(engine.eval::<i64>("sub(44, 2)")?, 42);
/// # Ok(())
/// # }
/// ```
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self;
}
/// Trait to register fallible custom functions returning [`Result`]`<`[`Dynamic`]`, `[`Box`]`<`[`EvalAltResult`][crate::EvalAltResult]`>>` with the [`Engine`].
pub trait RegisterResultFn<FN, ARGS> {
/// Register a custom fallible function with the [`Engine`].
///
/// # Example
///
/// ```
/// use rhai::{Engine, Dynamic, RegisterResultFn, EvalAltResult};
///
/// // Normal function
/// fn div(x: i64, y: i64) -> Result<Dynamic, Box<EvalAltResult>> {
/// if y == 0 {
/// // '.into()' automatically converts to 'Box<EvalAltResult::ErrorRuntime>'
/// Err("division by zero!".into())
/// } else {
/// Ok((x / y).into())
/// }
/// }
///
/// let mut engine = Engine::new();
///
/// // You must use the trait rhai::RegisterResultFn to get this method.
/// engine.register_result_fn("div", div);
///
/// engine.eval::<i64>("div(42, 0)")
/// .expect_err("expecting division by zero error!");
/// ```
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self;
}
// These types are used to build a unique _marker_ tuple type for each combination // These types are used to build a unique _marker_ tuple type for each combination
// of function parameter types in order to make each trait implementation unique. // of function parameter types in order to make each trait implementation unique.
// That is because stable Rust currently does not allow distinguishing implementations // That is because stable Rust currently does not allow distinguishing implementations
@ -77,7 +15,7 @@ pub trait RegisterResultFn<FN, ARGS> {
// //
// For example: // For example:
// //
// `RegisterFn<FN, (Mut<A>, B, Ref<C>), R>` // `NativeFunction<(Mut<A>, B, Ref<C>), R>`
// //
// will have the function prototype constraint to: // will have the function prototype constraint to:
// //
@ -107,7 +45,7 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
ref_t.clone() ref_t.clone()
} else if TypeId::of::<T>() == TypeId::of::<String>() { } else if TypeId::of::<T>() == TypeId::of::<String>() {
// If T is `String`, data must be `ImmutableString`, so map directly to it // If T is `String`, data must be `ImmutableString`, so map directly to it
*unsafe_cast_box(Box::new(mem::take(data).take_string().unwrap())).unwrap() unsafe_try_cast(mem::take(data).take_string().unwrap()).unwrap()
} else { } else {
// We consume the argument and then replace it with () - the argument is not supposed to be used again. // We consume the argument and then replace it with () - the argument is not supposed to be used again.
// This way, we avoid having to clone the argument again, because it is already a clone when passed here. // This way, we avoid having to clone the argument again, because it is already a clone when passed here.
@ -115,41 +53,10 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
} }
} }
/// This macro creates a closure wrapping a registered function. /// Trait to register custom functions with an [`Engine`].
macro_rules! make_func { pub trait RegisterNativeFunction<Args, Result> {
($fn:ident : $map:expr ; $($par:ident => $let:stmt => $convert:expr => $arg:expr),*) => { /// Register the function with an [`Engine`].
// ^ function pointer fn register_into(self, engine: &mut Engine, name: &str);
// ^ result mapping function
// ^ function parameter generic type name (A, B, C etc.)
// ^ argument let statement(e.g. let mut A ...)
// ^ dereferencing function
// ^ argument reference expression(like A, *B, &mut C etc)
Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
let mut _drain = args.iter_mut();
$($let $par = ($convert)(_drain.next().unwrap()); )*
// Call the function with each argument value
let r = $fn($($arg),*);
// Map the result
$map(r)
}) as Box<FnAny>
};
}
/// To Dynamic mapping function.
#[inline(always)]
pub fn map_dynamic(data: impl Variant + Clone) -> RhaiResult {
Ok(data.into_dynamic())
}
/// To Dynamic mapping function.
#[inline(always)]
pub fn map_result(data: RhaiResult) -> RhaiResult {
data
} }
macro_rules! def_register { macro_rules! def_register {
@ -160,37 +67,95 @@ macro_rules! def_register {
// ^ function ABI type // ^ function ABI type
// ^ function parameter generic type name (A, B, C etc.) // ^ function parameter generic type name (A, B, C etc.)
// ^ call argument(like A, *B, &mut C etc) // ^ call argument(like A, *B, &mut C etc)
// ^ function parameter marker type (T, Ref<T> or Mut<T>) // ^ function parameter marker type (T, Ref<T> or Mut<T>)
// ^ function parameter actual type (T, &T or &mut T) // ^ function parameter actual type (T, &T or &mut T)
// ^ argument let statement // ^ argument let statement
impl< impl<
$($par: Variant + Clone,)*
FN: Fn($($param),*) -> RET + SendSync + 'static, FN: Fn($($param),*) -> RET + SendSync + 'static,
$($par: Variant + Clone,)*
RET: Variant + Clone RET: Variant + Clone
> RegisterFn<FN, ($($mark,)*), RET> for Engine > RegisterNativeFunction<($($mark,)*), ()> for FN {
{
#[inline(always)] #[inline(always)]
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self { fn register_into(self, engine: &mut Engine, name: &str) {
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None, engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
&[$(TypeId::of::<$par>()),*], &[$(TypeId::of::<$par>()),*],
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $let => $clone => $arg),*)) CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
let mut _drain = args.iter_mut();
$($let $par = ($clone)(_drain.next().unwrap()); )*
// Call the function with each argument value
let r = self($($arg),*);
// Map the result
Ok(r.into_dynamic())
}) as Box<FnAny>)
); );
self
} }
} }
impl< impl<
FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> RET + SendSync + 'static,
$($par: Variant + Clone,)* $($par: Variant + Clone,)*
FN: Fn($($param),*) -> RhaiResult + SendSync + 'static, RET: Variant + Clone
> RegisterResultFn<FN, ($($mark,)*)> for Engine > RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
{
#[inline(always)] #[inline(always)]
fn register_result_fn(&mut self, name: &str, f: FN) -> &mut Self { fn register_into(self, engine: &mut Engine, name: &str) {
self.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None, engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
&[$(TypeId::of::<$par>()),*], &[$(TypeId::of::<$par>()),*],
CallableFunction::$abi(make_func!(f : map_result ; $($par => $let => $clone => $arg),*)) CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
let mut _drain = args.iter_mut();
$($let $par = ($clone)(_drain.next().unwrap()); )*
// Call the function with each argument value
let r = self(ctx, $($arg),*);
// Map the result
Ok(r.into_dynamic())
}) as Box<FnAny>)
);
}
}
impl<
FN: Fn($($param),*) -> RhaiResult + SendSync + 'static,
$($par: Variant + Clone,)*
> RegisterNativeFunction<($($mark,)*), RhaiResult> for FN {
#[inline(always)]
fn register_into(self, engine: &mut Engine, name: &str) {
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
&[$(TypeId::of::<$par>()),*],
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
let mut _drain = args.iter_mut();
$($let $par = ($clone)(_drain.next().unwrap()); )*
// Call the function with each argument value
self($($arg),*)
}) as Box<FnAny>)
);
}
}
impl<
FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> RhaiResult + SendSync + 'static,
$($par: Variant + Clone,)*
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), RhaiResult> for FN {
#[inline(always)]
fn register_into(self, engine: &mut Engine, name: &str) {
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
&[$(TypeId::of::<$par>()),*],
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
let mut _drain = args.iter_mut();
$($let $par = ($clone)(_drain.next().unwrap()); )*
// Call the function with each argument value
self(ctx, $($arg),*)
}) as Box<FnAny>)
); );
self
} }
} }

View File

@ -25,7 +25,7 @@
//! ## The Rust part //! ## The Rust part
//! //!
//! ```,no_run //! ```,no_run
//! use rhai::{Engine, EvalAltResult, RegisterFn}; //! use rhai::{Engine, EvalAltResult};
//! //!
//! fn main() -> Result<(), Box<EvalAltResult>> //! fn main() -> Result<(), Box<EvalAltResult>>
//! { //! {
@ -126,7 +126,7 @@ pub use ast::{FnAccess, AST};
pub use dynamic::Dynamic; pub use dynamic::Dynamic;
pub use engine::{Engine, EvalContext, OP_CONTAINS, OP_EQUALS}; pub use engine::{Engine, EvalContext, OP_CONTAINS, OP_EQUALS};
pub use fn_native::{FnPtr, NativeCallContext}; pub use fn_native::{FnPtr, NativeCallContext};
pub use fn_register::{RegisterFn, RegisterResultFn}; pub use fn_register::RegisterNativeFunction;
pub use module::{FnNamespace, Module}; pub use module::{FnNamespace, Module};
pub use parse_error::{LexError, ParseError, ParseErrorType}; pub use parse_error::{LexError, ParseError, ParseErrorType};
pub use result::EvalAltResult; pub use result::EvalAltResult;

View File

@ -175,12 +175,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
ar.push( ar.push(
mapper mapper
.call_dynamic(ctx, None, [item.clone()]) .call_dynamic(&ctx, None, [item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(mapper.fn_name()) => if fn_sig.starts_with(mapper.fn_name()) =>
{ {
mapper.call_dynamic(ctx, None, [item.clone(), (i as INT).into()]) mapper.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -207,12 +207,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
if filter if filter
.call_dynamic(ctx, None, [item.clone()]) .call_dynamic(&ctx, None, [item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -303,12 +303,12 @@ mod array_functions {
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
if filter if filter
.call_dynamic(ctx, None, [item.clone()]) .call_dynamic(&ctx, None, [item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -337,12 +337,12 @@ mod array_functions {
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
if filter if filter
.call_dynamic(ctx, None, [item.clone()]) .call_dynamic(&ctx, None, [item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -371,12 +371,12 @@ mod array_functions {
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
if !filter if !filter
.call_dynamic(ctx, None, [item.clone()]) .call_dynamic(&ctx, None, [item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [item.clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -407,12 +407,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
result = reducer result = reducer
.call_dynamic(ctx, None, [result.clone(), item.clone()]) .call_dynamic(&ctx, None, [result.clone(), item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(reducer.fn_name()) => if fn_sig.starts_with(reducer.fn_name()) =>
{ {
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()]) reducer.call_dynamic(&ctx, None, [result, item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -435,7 +435,7 @@ mod array_functions {
reducer: FnPtr, reducer: FnPtr,
initial: FnPtr, initial: FnPtr,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
let mut result = initial.call_dynamic(ctx, None, []).map_err(|err| { let mut result = initial.call_dynamic(&ctx, None, []).map_err(|err| {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce".to_string(), "reduce".to_string(),
ctx.source().unwrap_or("").to_string(), ctx.source().unwrap_or("").to_string(),
@ -446,12 +446,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate() { for (i, item) in array.iter().enumerate() {
result = reducer result = reducer
.call_dynamic(ctx, None, [result.clone(), item.clone()]) .call_dynamic(&ctx, None, [result.clone(), item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(reducer.fn_name()) => if fn_sig.starts_with(reducer.fn_name()) =>
{ {
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()]) reducer.call_dynamic(&ctx, None, [result, item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -477,12 +477,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate().rev() { for (i, item) in array.iter().enumerate().rev() {
result = reducer result = reducer
.call_dynamic(ctx, None, [result.clone(), item.clone()]) .call_dynamic(&ctx, None, [result.clone(), item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(reducer.fn_name()) => if fn_sig.starts_with(reducer.fn_name()) =>
{ {
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()]) reducer.call_dynamic(&ctx, None, [result, item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -505,7 +505,7 @@ mod array_functions {
reducer: FnPtr, reducer: FnPtr,
initial: FnPtr, initial: FnPtr,
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
let mut result = initial.call_dynamic(ctx, None, []).map_err(|err| { let mut result = initial.call_dynamic(&ctx, None, []).map_err(|err| {
Box::new(EvalAltResult::ErrorInFunctionCall( Box::new(EvalAltResult::ErrorInFunctionCall(
"reduce_rev".to_string(), "reduce_rev".to_string(),
ctx.source().unwrap_or("").to_string(), ctx.source().unwrap_or("").to_string(),
@ -516,12 +516,12 @@ mod array_functions {
for (i, item) in array.iter().enumerate().rev() { for (i, item) in array.iter().enumerate().rev() {
result = reducer result = reducer
.call_dynamic(ctx, None, [result.clone(), item.clone()]) .call_dynamic(&ctx, None, [result.clone(), item.clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(reducer.fn_name()) => if fn_sig.starts_with(reducer.fn_name()) =>
{ {
reducer.call_dynamic(ctx, None, [result, item.clone(), (i as INT).into()]) reducer.call_dynamic(&ctx, None, [result, item.clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -545,7 +545,7 @@ mod array_functions {
) -> Result<Dynamic, Box<EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
array.sort_by(|x, y| { array.sort_by(|x, y| {
comparer comparer
.call_dynamic(ctx, None, [x.clone(), y.clone()]) .call_dynamic(&ctx, None, [x.clone(), y.clone()])
.ok() .ok()
.and_then(|v| v.as_int().ok()) .and_then(|v| v.as_int().ok())
.map(|v| { .map(|v| {
@ -587,12 +587,12 @@ mod array_functions {
i -= 1; i -= 1;
if filter if filter
.call_dynamic(ctx, None, [array[i].clone()]) .call_dynamic(&ctx, None, [array[i].clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [array[i].clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [array[i].clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })
@ -647,12 +647,12 @@ mod array_functions {
i -= 1; i -= 1;
if !filter if !filter
.call_dynamic(ctx, None, [array[i].clone()]) .call_dynamic(&ctx, None, [array[i].clone()])
.or_else(|err| match *err { .or_else(|err| match *err {
EvalAltResult::ErrorFunctionNotFound(fn_sig, _) EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
if fn_sig.starts_with(filter.fn_name()) => if fn_sig.starts_with(filter.fn_name()) =>
{ {
filter.call_dynamic(ctx, None, [array[i].clone(), (i as INT).into()]) filter.call_dynamic(&ctx, None, [array[i].clone(), (i as INT).into()])
} }
_ => Err(err), _ => Err(err),
}) })

View File

@ -5,7 +5,7 @@ pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString,
use crate::RhaiResult; use crate::RhaiResult;
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,
}; };
#[cfg(not(features = "no_module"))] #[cfg(not(features = "no_module"))]

View File

@ -1,5 +1,5 @@
#![cfg(not(feature = "no_index"))] #![cfg(not(feature = "no_index"))]
use rhai::{Array, Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Array, Engine, EvalAltResult, INT};
#[test] #[test]
fn test_arrays() -> Result<(), Box<EvalAltResult>> { fn test_arrays() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,5 +1,5 @@
#![cfg(not(feature = "no_function"))] #![cfg(not(feature = "no_function"))]
use rhai::{Dynamic, Engine, EvalAltResult, FnPtr, Func, FuncArgs, RegisterFn, Scope, INT}; use rhai::{Dynamic, Engine, EvalAltResult, FnPtr, Func, FuncArgs, Scope, INT};
use std::{any::TypeId, iter::once}; use std::{any::TypeId, iter::once};
#[test] #[test]
@ -131,7 +131,7 @@ fn test_fn_ptr_raw() -> Result<(), Box<EvalAltResult>> {
let value = args[2].clone(); let value = args[2].clone();
let this_ptr = args.get_mut(0).unwrap(); let this_ptr = args.get_mut(0).unwrap();
fp.call_dynamic(context, Some(this_ptr), [value]) fp.call_dynamic(&context, Some(this_ptr), [value])
}, },
); );

View File

@ -1,7 +1,5 @@
#![cfg(not(feature = "no_function"))] #![cfg(not(feature = "no_function"))]
use rhai::{ use rhai::{Engine, EvalAltResult, FnPtr, NativeCallContext, ParseErrorType, Scope, INT};
Engine, EvalAltResult, FnPtr, NativeCallContext, ParseErrorType, RegisterFn, Scope, INT,
};
use std::any::TypeId; use std::any::TypeId;
use std::cell::RefCell; use std::cell::RefCell;
use std::mem::take; use std::mem::take;
@ -20,7 +18,7 @@ fn test_fn_ptr_curry_call() -> Result<(), Box<EvalAltResult>> {
&[TypeId::of::<FnPtr>(), TypeId::of::<INT>()], &[TypeId::of::<FnPtr>(), TypeId::of::<INT>()],
|context, args| { |context, args| {
let fn_ptr = std::mem::take(args[0]).cast::<FnPtr>(); let fn_ptr = std::mem::take(args[0]).cast::<FnPtr>();
fn_ptr.call_dynamic(context, None, [std::mem::take(args[1])]) fn_ptr.call_dynamic(&context, None, [std::mem::take(args[1])])
}, },
); );
@ -159,7 +157,7 @@ fn test_closures() -> Result<(), Box<EvalAltResult>> {
|context, args| { |context, args| {
let func = take(args[1]).cast::<FnPtr>(); let func = take(args[1]).cast::<FnPtr>();
func.call_dynamic(context, None, []) func.call_dynamic(&context, None, [])
}, },
); );
@ -343,7 +341,7 @@ fn test_closures_external() -> Result<(), Box<EvalAltResult>> {
let context = NativeCallContext::new(&engine, &fn_name, &lib); let context = NativeCallContext::new(&engine, &fn_name, &lib);
// Closure 'f' captures: the engine, the AST, and the curried function pointer // Closure 'f' captures: the engine, the AST, and the curried function pointer
let f = move |x: INT| fn_ptr.call_dynamic(context, None, [x.into()]); let f = move |x: INT| fn_ptr.call_dynamic(&context, None, [x.into()]);
assert_eq!(f(42)?.take_string(), Ok("hello42".to_string())); assert_eq!(f(42)?.take_string(), Ok("hello42".to_string()));

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, ParseErrorType, RegisterFn, Scope, INT}; use rhai::{Engine, EvalAltResult, ParseErrorType, Scope, INT};
#[test] #[test]
fn test_constant() -> Result<(), Box<EvalAltResult>> { fn test_constant() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,5 +1,5 @@
#![cfg(not(feature = "no_float"))] #![cfg(not(feature = "no_float"))]
use rhai::{Engine, EvalAltResult, RegisterFn, FLOAT}; use rhai::{Engine, EvalAltResult, FLOAT};
const EPSILON: FLOAT = 0.000_000_000_1; const EPSILON: FLOAT = 0.000_000_000_1;

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[test] #[test]
fn test_fn_ptr() -> Result<(), Box<EvalAltResult>> { fn test_fn_ptr() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,5 +1,5 @@
#![cfg(not(feature = "no_function"))] #![cfg(not(feature = "no_function"))]
use rhai::{Engine, EvalAltResult, FnNamespace, Module, ParseErrorType, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, FnNamespace, Module, ParseErrorType, INT};
#[test] #[test]
fn test_functions() -> Result<(), Box<EvalAltResult>> { fn test_functions() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,6 +1,6 @@
#![cfg(not(feature = "no_object"))] #![cfg(not(feature = "no_object"))]
use rhai::{Engine, EvalAltResult, ImmutableString, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, ImmutableString, INT};
#[test] #[test]
fn test_get_set() -> Result<(), Box<EvalAltResult>> { fn test_get_set() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,6 +1,6 @@
#![cfg(not(feature = "no_object"))] #![cfg(not(feature = "no_object"))]
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[test] #[test]
fn test_method_call() -> Result<(), Box<EvalAltResult>> { fn test_method_call() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[test] #[test]
fn test_mismatched_op() { fn test_mismatched_op() {

View File

@ -1,6 +1,6 @@
#![cfg(not(feature = "no_optimize"))] #![cfg(not(feature = "no_optimize"))]
use rhai::{Engine, EvalAltResult, OptimizationLevel, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, OptimizationLevel, INT};
#[test] #[test]
fn test_optimizer_run() -> Result<(), Box<EvalAltResult>> { fn test_optimizer_run() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, Scope, INT}; use rhai::{Engine, EvalAltResult, Scope, INT};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
#[cfg(not(feature = "only_i32"))] #[cfg(not(feature = "only_i32"))]

View File

@ -1,5 +1,5 @@
///! This test simulates an external command object that is driven by a script. ///! This test simulates an external command object that is driven by a script.
use rhai::{Engine, EvalAltResult, RegisterFn, Scope, INT}; use rhai::{Engine, EvalAltResult, Scope, INT};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
/// Simulate a command object. /// Simulate a command object.

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, ImmutableString, RegisterFn, Scope, INT}; use rhai::{Engine, EvalAltResult, ImmutableString, Scope, INT};
#[test] #[test]
fn test_string() -> Result<(), Box<EvalAltResult>> { fn test_string() -> Result<(), Box<EvalAltResult>> {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, LexError, ParseErrorType, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, LexError, ParseErrorType, INT};
#[test] #[test]
fn test_tokens_disabled() { fn test_tokens_disabled() {

View File

@ -1,4 +1,4 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT}; use rhai::{Engine, EvalAltResult, INT};
#[test] #[test]
fn test_type_of() -> Result<(), Box<EvalAltResult>> { fn test_type_of() -> Result<(), Box<EvalAltResult>> {