Deprecate RegisterFn and RegisterResultFn.
This commit is contained in:
parent
2f8a3c24c0
commit
d0922adb5b
@ -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
|
||||||
===============
|
===============
|
||||||
|
@ -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]
|
||||||
|
@ -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)]
|
||||||
|
@ -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::*;
|
||||||
//!
|
//!
|
||||||
|
@ -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::*;
|
||||||
|
@ -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::*;
|
||||||
|
@ -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::*;
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
///
|
///
|
||||||
|
@ -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();
|
||||||
///
|
///
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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),
|
||||||
})
|
})
|
||||||
|
@ -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"))]
|
||||||
|
@ -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>> {
|
||||||
|
@ -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])
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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()));
|
||||||
|
|
||||||
|
@ -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>> {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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>> {
|
||||||
|
@ -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>> {
|
||||||
|
@ -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>> {
|
||||||
|
@ -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>> {
|
||||||
|
@ -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() {
|
||||||
|
@ -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>> {
|
||||||
|
@ -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"))]
|
||||||
|
@ -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.
|
||||||
|
@ -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>> {
|
||||||
|
@ -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() {
|
||||||
|
@ -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>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user