diff --git a/src/func/call.rs b/src/func/call.rs index 87478c71..7e6b1c38 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -1,6 +1,7 @@ //! Implement function-calling mechanism for [`Engine`]. -use super::native::{CallableFunction, FnAny}; +use super::callable_function::CallableFunction; +use super::native::FnAny; use super::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn}; use crate::api::default_limits::MAX_DYNAMIC_PARAMETERS; use crate::ast::FnCallHashes; diff --git a/src/func/callable_function.rs b/src/func/callable_function.rs new file mode 100644 index 00000000..251c4d06 --- /dev/null +++ b/src/func/callable_function.rs @@ -0,0 +1,250 @@ +//! Module defining the standard Rhai function type. + +use super::native::{FnAny, FnPlugin, IteratorFn, SendSync}; +use crate::ast::FnAccess; +use crate::plugin::PluginFunction; +use crate::Shared; +use std::fmt; +#[cfg(feature = "no_std")] +use std::prelude::v1::*; + +/// A type encapsulating a function callable by Rhai. +#[derive(Clone)] +pub enum CallableFunction { + /// A pure native Rust function with all arguments passed by value. + Pure(Shared), + /// A native Rust object method with the first argument passed by reference, + /// and the rest passed by value. + Method(Shared), + /// An iterator function. + Iterator(IteratorFn), + /// A plugin function, + Plugin(Shared), + /// A script-defined function. + /// + /// Not available under `no_function`. + #[cfg(not(feature = "no_function"))] + Script(Shared), +} + +impl fmt::Debug for CallableFunction { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Pure(_) => write!(f, "NativePureFunction"), + Self::Method(_) => write!(f, "NativeMethod"), + Self::Iterator(_) => write!(f, "NativeIterator"), + Self::Plugin(_) => write!(f, "PluginFunction"), + + #[cfg(not(feature = "no_function"))] + Self::Script(fn_def) => fmt::Debug::fmt(fn_def, f), + } + } +} + +impl fmt::Display for CallableFunction { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Pure(_) => write!(f, "NativePureFunction"), + Self::Method(_) => write!(f, "NativeMethod"), + Self::Iterator(_) => write!(f, "NativeIterator"), + Self::Plugin(_) => write!(f, "PluginFunction"), + + #[cfg(not(feature = "no_function"))] + CallableFunction::Script(s) => fmt::Display::fmt(s, f), + } + } +} + +impl CallableFunction { + /// Is this a pure native Rust function? + #[inline] + #[must_use] + pub fn is_pure(&self) -> bool { + match self { + Self::Pure(_) => true, + Self::Method(_) | Self::Iterator(_) => false, + + Self::Plugin(p) => !p.is_method_call(), + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => false, + } + } + /// Is this a native Rust method function? + #[inline] + #[must_use] + pub fn is_method(&self) -> bool { + match self { + Self::Method(_) => true, + Self::Pure(_) | Self::Iterator(_) => false, + + Self::Plugin(p) => p.is_method_call(), + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => false, + } + } + /// Is this an iterator function? + #[inline] + #[must_use] + pub const fn is_iter(&self) -> bool { + match self { + Self::Iterator(_) => true, + Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => false, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => false, + } + } + /// Is this a script-defined function? + #[inline] + #[must_use] + pub const fn is_script(&self) -> bool { + match self { + #[cfg(not(feature = "no_function"))] + Self::Script(_) => true, + + Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => false, + } + } + /// Is this a plugin function? + #[inline] + #[must_use] + pub const fn is_plugin_fn(&self) -> bool { + match self { + Self::Plugin(_) => true, + Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => false, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => false, + } + } + /// Is this a native Rust function? + #[inline] + #[must_use] + pub const fn is_native(&self) -> bool { + match self { + Self::Pure(_) | Self::Method(_) => true, + Self::Plugin(_) => true, + Self::Iterator(_) => true, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => false, + } + } + /// Get the access mode. + #[inline] + #[must_use] + pub fn access(&self) -> FnAccess { + match self { + Self::Plugin(_) => FnAccess::Public, + Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => FnAccess::Public, + + #[cfg(not(feature = "no_function"))] + Self::Script(f) => f.access, + } + } + /// Get a shared reference to a native Rust function. + #[inline] + #[must_use] + pub fn get_native_fn(&self) -> Option<&Shared> { + match self { + Self::Pure(f) | Self::Method(f) => Some(f), + Self::Iterator(_) | Self::Plugin(_) => None, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => None, + } + } + /// Get a shared reference to a script-defined function definition. + /// + /// Not available under `no_function`. + #[cfg(not(feature = "no_function"))] + #[inline] + #[must_use] + pub const fn get_script_fn_def(&self) -> Option<&Shared> { + match self { + Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => None, + Self::Script(f) => Some(f), + } + } + /// Get a reference to an iterator function. + #[inline] + #[must_use] + pub fn get_iter_fn(&self) -> Option { + match self { + Self::Iterator(f) => Some(*f), + Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => None, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => None, + } + } + /// Get a shared reference to a plugin function. + #[inline] + #[must_use] + pub fn get_plugin_fn(&self) -> Option<&Shared> { + match self { + Self::Plugin(f) => Some(f), + Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => None, + + #[cfg(not(feature = "no_function"))] + Self::Script(_) => None, + } + } + /// Create a new [`CallableFunction::Pure`]. + #[inline(always)] + #[must_use] + pub fn from_pure(func: Box) -> Self { + Self::Pure(func.into()) + } + /// Create a new [`CallableFunction::Method`]. + #[inline(always)] + #[must_use] + pub fn from_method(func: Box) -> Self { + Self::Method(func.into()) + } + /// Create a new [`CallableFunction::Plugin`]. + #[inline(always)] + #[must_use] + pub fn from_plugin(func: impl PluginFunction + 'static + SendSync) -> Self { + Self::Plugin((Box::new(func) as Box).into()) + } +} + +impl From for CallableFunction { + #[inline(always)] + fn from(func: IteratorFn) -> Self { + Self::Iterator(func) + } +} + +#[cfg(not(feature = "no_function"))] +impl From for CallableFunction { + #[inline(always)] + fn from(_func: crate::ast::ScriptFnDef) -> Self { + Self::Script(_func.into()) + } +} + +#[cfg(not(feature = "no_function"))] +impl From> for CallableFunction { + #[inline(always)] + fn from(_func: Shared) -> Self { + Self::Script(_func) + } +} + +impl From for CallableFunction { + #[inline(always)] + fn from(func: T) -> Self { + Self::from_plugin(func) + } +} + +impl From> for CallableFunction { + #[inline(always)] + fn from(func: Shared) -> Self { + Self::Plugin(func) + } +} diff --git a/src/func/mod.rs b/src/func/mod.rs index 1d5a0841..dcae0482 100644 --- a/src/func/mod.rs +++ b/src/func/mod.rs @@ -3,6 +3,7 @@ pub mod args; pub mod builtin; pub mod call; +pub mod callable_function; pub mod func; pub mod hashing; pub mod native; @@ -13,6 +14,7 @@ pub mod script; pub use args::FuncArgs; pub use builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn}; pub use call::FnCallArgs; +pub use callable_function::CallableFunction; #[cfg(not(feature = "no_function"))] pub use func::Func; pub use hashing::{ @@ -20,8 +22,8 @@ pub use hashing::{ combine_hashes, get_hasher, }; pub use native::{ - shared_make_mut, shared_take, shared_take_or_clone, shared_try_take, shared_write_lock, - CallableFunction, FnAny, FnPlugin, IteratorFn, Locked, NativeCallContext, SendSync, Shared, + shared_make_mut, shared_take, shared_take_or_clone, shared_try_take, shared_write_lock, FnAny, + FnPlugin, IteratorFn, Locked, NativeCallContext, SendSync, Shared, }; pub use plugin::PluginFunction; pub use register::RegisterNativeFunction; diff --git a/src/func/native.rs b/src/func/native.rs index f23d04b4..56a8edfc 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -1,7 +1,7 @@ //! Module defining interfaces to native-Rust functions. use super::call::FnCallArgs; -use crate::ast::{FnAccess, FnCallHashes}; +use crate::ast::FnCallHashes; use crate::engine::{EvalState, Imports}; use crate::plugin::PluginFunction; use crate::tokenizer::{Token, TokenizeState}; @@ -10,9 +10,9 @@ use crate::{ calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, FuncArgs, Module, Position, RhaiResult, StaticVec, }; +use std::any::type_name; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::{any::type_name, fmt}; /// Trait that maps to `Send + Sync` only under the `sync` feature. #[cfg(feature = "sync")] @@ -414,244 +414,3 @@ pub type OnVarCallback = Box< + Sync + 'static, >; - -/// A type encapsulating a function callable by Rhai. -#[derive(Clone)] -pub enum CallableFunction { - /// A pure native Rust function with all arguments passed by value. - Pure(Shared), - /// A native Rust object method with the first argument passed by reference, - /// and the rest passed by value. - Method(Shared), - /// An iterator function. - Iterator(IteratorFn), - /// A plugin function, - Plugin(Shared), - /// A script-defined function. - /// - /// Not available under `no_function`. - #[cfg(not(feature = "no_function"))] - Script(Shared), -} - -impl fmt::Debug for CallableFunction { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Pure(_) => write!(f, "NativePureFunction"), - Self::Method(_) => write!(f, "NativeMethod"), - Self::Iterator(_) => write!(f, "NativeIterator"), - Self::Plugin(_) => write!(f, "PluginFunction"), - - #[cfg(not(feature = "no_function"))] - Self::Script(fn_def) => fmt::Debug::fmt(fn_def, f), - } - } -} - -impl fmt::Display for CallableFunction { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Pure(_) => write!(f, "NativePureFunction"), - Self::Method(_) => write!(f, "NativeMethod"), - Self::Iterator(_) => write!(f, "NativeIterator"), - Self::Plugin(_) => write!(f, "PluginFunction"), - - #[cfg(not(feature = "no_function"))] - CallableFunction::Script(s) => fmt::Display::fmt(s, f), - } - } -} - -impl CallableFunction { - /// Is this a pure native Rust function? - #[inline] - #[must_use] - pub fn is_pure(&self) -> bool { - match self { - Self::Pure(_) => true, - Self::Method(_) | Self::Iterator(_) => false, - - Self::Plugin(p) => !p.is_method_call(), - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, - } - } - /// Is this a native Rust method function? - #[inline] - #[must_use] - pub fn is_method(&self) -> bool { - match self { - Self::Method(_) => true, - Self::Pure(_) | Self::Iterator(_) => false, - - Self::Plugin(p) => p.is_method_call(), - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, - } - } - /// Is this an iterator function? - #[inline] - #[must_use] - pub const fn is_iter(&self) -> bool { - match self { - Self::Iterator(_) => true, - Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => false, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, - } - } - /// Is this a script-defined function? - #[inline] - #[must_use] - pub const fn is_script(&self) -> bool { - match self { - #[cfg(not(feature = "no_function"))] - Self::Script(_) => true, - - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => false, - } - } - /// Is this a plugin function? - #[inline] - #[must_use] - pub const fn is_plugin_fn(&self) -> bool { - match self { - Self::Plugin(_) => true, - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => false, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, - } - } - /// Is this a native Rust function? - #[inline] - #[must_use] - pub const fn is_native(&self) -> bool { - match self { - Self::Pure(_) | Self::Method(_) => true, - Self::Plugin(_) => true, - Self::Iterator(_) => true, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, - } - } - /// Get the access mode. - #[inline] - #[must_use] - pub fn access(&self) -> FnAccess { - match self { - Self::Plugin(_) => FnAccess::Public, - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => FnAccess::Public, - - #[cfg(not(feature = "no_function"))] - Self::Script(f) => f.access, - } - } - /// Get a shared reference to a native Rust function. - #[inline] - #[must_use] - pub fn get_native_fn(&self) -> Option<&Shared> { - match self { - Self::Pure(f) | Self::Method(f) => Some(f), - Self::Iterator(_) | Self::Plugin(_) => None, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, - } - } - /// Get a shared reference to a script-defined function definition. - /// - /// Not available under `no_function`. - #[cfg(not(feature = "no_function"))] - #[inline] - #[must_use] - pub const fn get_script_fn_def(&self) -> Option<&Shared> { - match self { - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => None, - Self::Script(f) => Some(f), - } - } - /// Get a reference to an iterator function. - #[inline] - #[must_use] - pub fn get_iter_fn(&self) -> Option { - match self { - Self::Iterator(f) => Some(*f), - Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => None, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, - } - } - /// Get a shared reference to a plugin function. - #[inline] - #[must_use] - pub fn get_plugin_fn(&self) -> Option<&Shared> { - match self { - Self::Plugin(f) => Some(f), - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => None, - - #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, - } - } - /// Create a new [`CallableFunction::Pure`]. - #[inline(always)] - #[must_use] - pub fn from_pure(func: Box) -> Self { - Self::Pure(func.into()) - } - /// Create a new [`CallableFunction::Method`]. - #[inline(always)] - #[must_use] - pub fn from_method(func: Box) -> Self { - Self::Method(func.into()) - } - /// Create a new [`CallableFunction::Plugin`]. - #[inline(always)] - #[must_use] - pub fn from_plugin(func: impl PluginFunction + 'static + SendSync) -> Self { - Self::Plugin((Box::new(func) as Box).into()) - } -} - -impl From for CallableFunction { - #[inline(always)] - fn from(func: IteratorFn) -> Self { - Self::Iterator(func) - } -} - -#[cfg(not(feature = "no_function"))] -impl From for CallableFunction { - #[inline(always)] - fn from(_func: crate::ast::ScriptFnDef) -> Self { - Self::Script(_func.into()) - } -} - -#[cfg(not(feature = "no_function"))] -impl From> for CallableFunction { - #[inline(always)] - fn from(_func: Shared) -> Self { - Self::Script(_func) - } -} - -impl From for CallableFunction { - #[inline(always)] - fn from(func: T) -> Self { - Self::from_plugin(func) - } -} - -impl From> for CallableFunction { - #[inline(always)] - fn from(func: Shared) -> Self { - Self::Plugin(func) - } -} diff --git a/src/func/register.rs b/src/func/register.rs index e317f51b..7230ab02 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -2,8 +2,9 @@ #![allow(non_snake_case)] -use crate::func::call::FnCallArgs; -use crate::func::native::{CallableFunction, FnAny, SendSync}; +use super::call::FnCallArgs; +use super::callable_function::CallableFunction; +use super::native::{FnAny, SendSync}; use crate::r#unsafe::unsafe_try_cast; use crate::tokenizer::Position; use crate::types::dynamic::{DynamicWriteLock, Variant}; diff --git a/src/func/script.rs b/src/func/script.rs index 383dd400..1bb56e3f 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -1,9 +1,9 @@ //! Implement script function-calling mechanism for [`Engine`]. #![cfg(not(feature = "no_function"))] +use super::call::FnCallArgs; use crate::ast::ScriptFnDef; use crate::engine::{EvalState, Imports}; -use crate::func::call::FnCallArgs; use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::{Dynamic, Engine, EvalAltResult, Module, Position, RhaiResult, Scope, StaticVec}; use std::mem; diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 26251386..09d24950 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -611,14 +611,11 @@ impl fmt::Display for Dynamic { #[cfg(feature = "decimal")] Union::Decimal(ref value, _, _) => fmt::Display::fmt(value, f), #[cfg(not(feature = "no_index"))] - Union::Array(ref value, _, _) => fmt::Debug::fmt(value, f), + Union::Array(_, _, _) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_index"))] - Union::Blob(ref value, _, _) => fmt::Debug::fmt(value, f), + Union::Blob(_, _, _) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_object"))] - Union::Map(ref value, _, _) => { - f.write_str("#")?; - fmt::Debug::fmt(value, f) - } + Union::Map(_, _, _) => fmt::Debug::fmt(self, f), Union::FnPtr(ref value, _, _) => fmt::Display::fmt(value, f), #[cfg(not(feature = "no_std"))] Union::TimeStamp(_, _, _) => f.write_str(""),