diff --git a/src/any.rs b/src/any.rs index a96bcca2..2682115b 100644 --- a/src/any.rs +++ b/src/any.rs @@ -93,7 +93,7 @@ pub trait Variant: Any + Send + Sync { fn as_mut_any(&mut self) -> &mut dyn Any; /// Convert this `Variant` trait object to an `Any` trait object. - fn as_box_any(self) -> Box; + fn as_box_any(self: Box) -> Box; /// Get the name of this type. fn type_name(&self) -> &'static str; diff --git a/src/api.rs b/src/api.rs index 096ba00d..95423d8e 100644 --- a/src/api.rs +++ b/src/api.rs @@ -4,6 +4,9 @@ use crate::any::{Dynamic, Variant}; use crate::engine::{make_getter, make_setter, Engine, State, FUNC_INDEXER}; use crate::error::ParseError; use crate::fn_call::FuncArgs; +use crate::fn_native::{ + IteratorCallback, ObjectGetCallback, ObjectIndexerCallback, ObjectSetCallback, +}; use crate::fn_register::RegisterFn; use crate::optimize::{optimize_into_ast, OptimizationLevel}; use crate::parser::{parse, parse_global_expr, AST}; @@ -22,56 +25,10 @@ use crate::stdlib::{ mem, string::{String, ToString}, }; + #[cfg(not(feature = "no_std"))] use crate::stdlib::{fs::File, io::prelude::*, path::PathBuf}; -// Define callback function types -#[cfg(feature = "sync")] -pub trait ObjectGetCallback: Fn(&mut T) -> U + Send + Sync + 'static {} -#[cfg(feature = "sync")] -impl U + Send + Sync + 'static, T, U> ObjectGetCallback for F {} - -#[cfg(not(feature = "sync"))] -pub trait ObjectGetCallback: Fn(&mut T) -> U + 'static {} -#[cfg(not(feature = "sync"))] -impl U + 'static, T, U> ObjectGetCallback for F {} - -#[cfg(feature = "sync")] -pub trait ObjectSetCallback: Fn(&mut T, U) + Send + Sync + 'static {} -#[cfg(feature = "sync")] -impl ObjectSetCallback for F {} - -#[cfg(not(feature = "sync"))] -pub trait ObjectSetCallback: Fn(&mut T, U) + 'static {} -#[cfg(not(feature = "sync"))] -impl ObjectSetCallback for F {} - -#[cfg(feature = "sync")] -pub trait ObjectIndexerCallback: Fn(&mut T, X) -> U + Send + Sync + 'static {} -#[cfg(feature = "sync")] -impl U + Send + Sync + 'static, T, X, U> ObjectIndexerCallback for F {} - -#[cfg(not(feature = "sync"))] -pub trait ObjectIndexerCallback: Fn(&mut T, X) -> U + 'static {} -#[cfg(not(feature = "sync"))] -impl U + 'static, T, X, U> ObjectIndexerCallback for F {} - -#[cfg(feature = "sync")] -pub trait IteratorCallback: - Fn(Dynamic) -> Box> + Send + Sync + 'static -{ -} -#[cfg(feature = "sync")] -impl Box> + Send + Sync + 'static> IteratorCallback - for F -{ -} - -#[cfg(not(feature = "sync"))] -pub trait IteratorCallback: Fn(Dynamic) -> Box> + 'static {} -#[cfg(not(feature = "sync"))] -impl Box> + 'static> IteratorCallback for F {} - /// Engine public API impl Engine { /// Register a custom type for use with the `Engine`. diff --git a/src/engine.rs b/src/engine.rs index d0889af0..301bbfca 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -3,7 +3,7 @@ use crate::any::{Dynamic, Union}; use crate::calc_fn_hash; use crate::error::ParseErrorType; -use crate::fn_native::{FnCallArgs, NativeFunctionABI}; +use crate::fn_native::{FnCallArgs, NativeFunctionABI, PrintCallback}; use crate::optimize::OptimizationLevel; use crate::packages::{ CorePackage, Package, PackageLibrary, PackageStore, PackagesCollection, StandardPackage, @@ -293,18 +293,9 @@ pub struct Engine { pub(crate) type_names: HashMap, /// Closure for implementing the `print` command. - #[cfg(feature = "sync")] - pub(crate) print: Box, - /// Closure for implementing the `print` command. - #[cfg(not(feature = "sync"))] - pub(crate) print: Box, - + pub(crate) print: Box, /// Closure for implementing the `debug` command. - #[cfg(feature = "sync")] - pub(crate) debug: Box, - /// Closure for implementing the `debug` command. - #[cfg(not(feature = "sync"))] - pub(crate) debug: Box, + pub(crate) debug: Box, /// Optimize the AST after compilation. pub(crate) optimization_level: OptimizationLevel, diff --git a/src/fn_native.rs b/src/fn_native.rs index 4bb7fde1..bfc9311b 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -17,6 +17,58 @@ pub type IteratorFn = dyn Fn(Dynamic) -> Box> + Sen #[cfg(not(feature = "sync"))] pub type IteratorFn = dyn Fn(Dynamic) -> Box>; +#[cfg(feature = "sync")] +pub type PrintCallback = dyn Fn(&str) + Send + Sync + 'static; +#[cfg(not(feature = "sync"))] +pub type PrintCallback = dyn Fn(&str) + 'static; + +// Define callback function types +#[cfg(feature = "sync")] +pub trait ObjectGetCallback: Fn(&mut T) -> U + Send + Sync + 'static {} +#[cfg(feature = "sync")] +impl U + Send + Sync + 'static, T, U> ObjectGetCallback for F {} + +#[cfg(not(feature = "sync"))] +pub trait ObjectGetCallback: Fn(&mut T) -> U + 'static {} +#[cfg(not(feature = "sync"))] +impl U + 'static, T, U> ObjectGetCallback for F {} + +#[cfg(feature = "sync")] +pub trait ObjectSetCallback: Fn(&mut T, U) + Send + Sync + 'static {} +#[cfg(feature = "sync")] +impl ObjectSetCallback for F {} + +#[cfg(not(feature = "sync"))] +pub trait ObjectSetCallback: Fn(&mut T, U) + 'static {} +#[cfg(not(feature = "sync"))] +impl ObjectSetCallback for F {} + +#[cfg(feature = "sync")] +pub trait ObjectIndexerCallback: Fn(&mut T, X) -> U + Send + Sync + 'static {} +#[cfg(feature = "sync")] +impl U + Send + Sync + 'static, T, X, U> ObjectIndexerCallback for F {} + +#[cfg(not(feature = "sync"))] +pub trait ObjectIndexerCallback: Fn(&mut T, X) -> U + 'static {} +#[cfg(not(feature = "sync"))] +impl U + 'static, T, X, U> ObjectIndexerCallback for F {} + +#[cfg(feature = "sync")] +pub trait IteratorCallback: + Fn(Dynamic) -> Box> + Send + Sync + 'static +{ +} +#[cfg(feature = "sync")] +impl Box> + Send + Sync + 'static> IteratorCallback + for F +{ +} + +#[cfg(not(feature = "sync"))] +pub trait IteratorCallback: Fn(Dynamic) -> Box> + 'static {} +#[cfg(not(feature = "sync"))] +impl Box> + 'static> IteratorCallback for F {} + /// A type representing the type of ABI of a native Rust function. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum NativeFunctionABI { @@ -28,6 +80,7 @@ pub enum NativeFunctionABI { } /// A trait implemented by all native Rust functions that are callable by Rhai. +#[cfg(not(feature = "sync"))] pub trait NativeCallable { /// Get the ABI type of a native Rust function. fn abi(&self) -> NativeFunctionABI; @@ -35,6 +88,15 @@ pub trait NativeCallable { fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result>; } +/// A trait implemented by all native Rust functions that are callable by Rhai. +#[cfg(feature = "sync")] +pub trait NativeCallable: Send + Sync { + /// Get the ABI type of a native Rust function. + fn abi(&self) -> NativeFunctionABI; + /// Call a native Rust function. + fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result>; +} + /// A type encapsulating a native Rust function callable by Rhai. pub struct NativeFunction(Box, NativeFunctionABI); diff --git a/src/fn_register.rs b/src/fn_register.rs index 28c15c7f..55271ae1 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -119,14 +119,14 @@ pub struct Mut(T); /// Dereference into &mut. #[inline(always)] -pub fn by_ref(data: &mut Dynamic) -> &mut T { +pub fn by_ref(data: &mut Dynamic) -> &mut T { // Directly cast the &mut Dynamic into &mut T to access the underlying data. data.downcast_mut::().unwrap() } /// Dereference into value. #[inline(always)] -pub fn by_value(data: &mut Dynamic) -> T { +pub fn by_value(data: &mut Dynamic) -> T { // 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. mem::take(data).cast::() diff --git a/src/module.rs b/src/module.rs index 83da428c..089acd3d 100644 --- a/src/module.rs +++ b/src/module.rs @@ -31,6 +31,7 @@ use crate::stdlib::{ }; /// A trait that encapsulates a module resolution service. +#[cfg(not(feature = "sync"))] pub trait ModuleResolver { /// Resolve a module based on a path string. fn resolve( @@ -42,6 +43,19 @@ pub trait ModuleResolver { ) -> Result>; } +/// A trait that encapsulates a module resolution service. +#[cfg(feature = "sync")] +pub trait ModuleResolver: Send + Sync { + /// Resolve a module based on a path string. + fn resolve( + &self, + engine: &Engine, + scope: Scope, + path: &str, + pos: Position, + ) -> Result>; +} + /// Default function access mode. const DEF_ACCESS: FnAccess = FnAccess::Public; diff --git a/tests/modules.rs b/tests/modules.rs index 52f6818e..acf3c0e6 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -83,6 +83,7 @@ fn test_module_resolver() -> Result<(), Box> { } #[test] +#[cfg(not(feature = "no_function"))] fn test_module_from_ast() -> Result<(), Box> { let mut engine = Engine::new(); @@ -100,7 +101,7 @@ fn test_module_from_ast() -> Result<(), Box> { x + 1 } fn add_len(x, y) { - x + y.len() + x + len(y) } private fn hidden() { throw "you shouldn't see me!";