2021-12-20 15:13:00 +01:00
|
|
|
//! Module defining the standard Rhai function type.
|
|
|
|
|
2022-11-17 11:05:52 +01:00
|
|
|
use super::native::{FnAny, FnPlugin, IteratorFn, SendSync};
|
2021-12-20 15:13:00 +01:00
|
|
|
use crate::ast::FnAccess;
|
|
|
|
use crate::plugin::PluginFunction;
|
|
|
|
use crate::Shared;
|
|
|
|
use std::fmt;
|
|
|
|
#[cfg(feature = "no_std")]
|
|
|
|
use std::prelude::v1::*;
|
|
|
|
|
2022-11-17 11:05:52 +01:00
|
|
|
/// _(internals)_ A type encapsulating a function callable by Rhai.
|
|
|
|
/// Exported under the `internals` feature only.
|
2021-12-20 15:13:00 +01:00
|
|
|
#[derive(Clone)]
|
2022-04-26 10:36:24 +02:00
|
|
|
#[non_exhaustive]
|
2021-12-20 15:13:00 +01:00
|
|
|
pub enum CallableFunction {
|
|
|
|
/// A pure native Rust function with all arguments passed by value.
|
|
|
|
Pure(Shared<FnAny>),
|
|
|
|
/// A native Rust object method with the first argument passed by reference,
|
|
|
|
/// and the rest passed by value.
|
|
|
|
Method(Shared<FnAny>),
|
|
|
|
/// An iterator function.
|
2022-01-27 16:55:32 +01:00
|
|
|
Iterator(Shared<IteratorFn>),
|
2021-12-20 15:13:00 +01:00
|
|
|
/// A plugin function,
|
|
|
|
Plugin(Shared<FnPlugin>),
|
|
|
|
/// A script-defined function.
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
Script(Shared<crate::ast::ScriptFnDef>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for CallableFunction {
|
2022-09-27 02:52:39 +02:00
|
|
|
#[cold]
|
|
|
|
#[inline(never)]
|
2021-12-20 15:13:00 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
2022-10-27 07:38:21 +02:00
|
|
|
Self::Pure(..) => f.write_str("NativePureFunction"),
|
|
|
|
Self::Method(..) => f.write_str("NativeMethod"),
|
|
|
|
Self::Iterator(..) => f.write_str("NativeIterator"),
|
|
|
|
Self::Plugin(..) => f.write_str("PluginFunction"),
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[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 {
|
2022-10-27 07:38:21 +02:00
|
|
|
Self::Pure(..) => f.write_str("NativePureFunction"),
|
|
|
|
Self::Method(..) => f.write_str("NativeMethod"),
|
|
|
|
Self::Iterator(..) => f.write_str("NativeIterator"),
|
|
|
|
Self::Plugin(..) => f.write_str("PluginFunction"),
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-01-03 16:16:47 +01:00
|
|
|
Self::Script(s) => fmt::Display::fmt(s, f),
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CallableFunction {
|
|
|
|
/// Is this a pure native Rust function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn is_pure(&self) -> bool {
|
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Pure(..) => true,
|
|
|
|
Self::Method(..) | Self::Iterator(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
Self::Plugin(p) => !p.is_method_call(),
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Is this a native Rust method function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn is_method(&self) -> bool {
|
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Method(..) => true,
|
|
|
|
Self::Pure(..) | Self::Iterator(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
Self::Plugin(p) => p.is_method_call(),
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Is this an iterator function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub const fn is_iter(&self) -> bool {
|
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Iterator(..) => true,
|
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Plugin(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Is this a script-defined function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub const fn is_script(&self) -> bool {
|
2021-12-21 06:03:39 +01:00
|
|
|
#[cfg(feature = "no_function")]
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2021-12-20 15:13:00 +01:00
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => true,
|
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) | Self::Plugin(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Is this a plugin function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub const fn is_plugin_fn(&self) -> bool {
|
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Plugin(..) => true,
|
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Is this a native Rust function?
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub const fn is_native(&self) -> bool {
|
2021-12-21 06:03:39 +01:00
|
|
|
#[cfg(feature = "no_function")]
|
|
|
|
return true;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2021-12-20 15:13:00 +01:00
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Pure(..) | Self::Method(..) => true,
|
|
|
|
Self::Plugin(..) => true,
|
|
|
|
Self::Iterator(..) => true,
|
|
|
|
Self::Script(..) => false,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Get the access mode.
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn access(&self) -> FnAccess {
|
2021-12-21 06:03:39 +01:00
|
|
|
#[cfg(feature = "no_function")]
|
|
|
|
return FnAccess::Public;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2021-12-20 15:13:00 +01:00
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Plugin(..) => FnAccess::Public,
|
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => FnAccess::Public,
|
2021-12-20 15:13:00 +01:00
|
|
|
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<FnAny>> {
|
|
|
|
match self {
|
|
|
|
Self::Pure(f) | Self::Method(f) => Some(f),
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Iterator(..) | Self::Plugin(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// 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<crate::ast::ScriptFnDef>> {
|
|
|
|
match self {
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) | Self::Plugin(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
Self::Script(f) => Some(f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Get a reference to an iterator function.
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
2022-01-27 16:55:32 +01:00
|
|
|
pub fn get_iter_fn(&self) -> Option<&IteratorFn> {
|
2021-12-20 15:13:00 +01:00
|
|
|
match self {
|
2022-07-05 10:26:38 +02:00
|
|
|
Self::Iterator(f) => Some(&**f),
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Plugin(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/// Get a shared reference to a plugin function.
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn get_plugin_fn(&self) -> Option<&Shared<FnPlugin>> {
|
|
|
|
match self {
|
|
|
|
Self::Plugin(f) => Some(f),
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-08 02:46:14 +01:00
|
|
|
Self::Script(..) => None,
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
impl From<crate::ast::ScriptFnDef> for CallableFunction {
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(_func: crate::ast::ScriptFnDef) -> Self {
|
|
|
|
Self::Script(_func.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
impl From<Shared<crate::ast::ScriptFnDef>> for CallableFunction {
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(_func: Shared<crate::ast::ScriptFnDef>) -> Self {
|
|
|
|
Self::Script(_func)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: PluginFunction + 'static + SendSync> From<T> for CallableFunction {
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(func: T) -> Self {
|
2022-11-17 11:05:52 +01:00
|
|
|
Self::Plugin(Shared::new(func))
|
2021-12-20 15:13:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Shared<FnPlugin>> for CallableFunction {
|
|
|
|
#[inline(always)]
|
|
|
|
fn from(func: Shared<FnPlugin>) -> Self {
|
|
|
|
Self::Plugin(func)
|
|
|
|
}
|
|
|
|
}
|