DynamicFunction

Struct DynamicFunction 

Source
pub struct DynamicFunction<'env> { /* private fields */ }
Available on crate feature functions only.
Expand description

A dynamic representation of a function.

This type can be used to represent any callable that satisfies Fn (or the reflection-based equivalent, ReflectFn). That is, any function or closure that does not mutably borrow data from its environment.

For functions that do need to capture their environment mutably (i.e. mutable closures), see DynamicFunctionMut.

See the module-level documentation for more information.

You will generally not need to construct this manually. Instead, many functions and closures can be automatically converted using the IntoFunction trait.

§Example

Most of the time, a DynamicFunction can be created using the IntoFunction trait:

fn add(a: i32, b: i32) -> i32 {
  a + b
}

// Convert the function into a dynamic function using `IntoFunction::into_function`:
let mut func: DynamicFunction = add.into_function();

// Dynamically call it:
let args = ArgList::default().with_owned(25_i32).with_owned(75_i32);
let value = func.call(args).unwrap().unwrap_owned();

// Check the result:
assert_eq!(value.try_downcast_ref::<i32>(), Some(&100));

Implementations§

Source§

impl<'env> DynamicFunction<'env>

Source

pub fn new<F: for<'a> Fn(ArgList<'a>) -> FunctionResult<'a> + Send + Sync + 'env>( func: F, info: impl TryInto<FunctionInfo, Error: Debug>, ) -> Self

Create a new DynamicFunction.

The given function can be used to call out to any other callable, including functions, closures, or methods.

It’s important that the function signature matches the provided FunctionInfo. as this will be used to validate arguments when calling the function. This is also required in order for function overloading to work correctly.

§Panics

This function may panic for any of the following reasons:

Source

pub fn with_name(self, name: impl Into<Cow<'static, str>>) -> Self

Set the name of the function.

For DynamicFunctions created using IntoFunction, the default name will always be the full path to the function as returned by core::any::type_name, unless the function is a closure, anonymous function, or function pointer, in which case the name will be None.

Source

pub fn with_overload<'a, F: IntoFunction<'a, Marker>, Marker>( self, function: F, ) -> DynamicFunction<'a>
where 'env: 'a,

Add an overload to this function.

Overloads allow a single DynamicFunction to represent multiple functions of different signatures.

This can be used to handle multiple monomorphizations of a generic function or to allow functions with a variable number of arguments.

Any functions with the same argument signature will be overwritten by the one from the new function, F. For example, if the existing function had the signature (i32, i32) -> i32, and the new function, F, also had the signature (i32, i32) -> i32, the one from F would replace the one from the existing function.

Overloaded functions retain the name of the original function.

§Panics

Panics if the function, F, contains a signature already found in this function.

For a non-panicking version, see try_with_overload.

§Examples
fn add<T: Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

// Currently, the only generic type `func` supports is `i32`:
let mut func = add::<i32>.into_function();

// However, we can add an overload to handle `f32` as well:
func = func.with_overload(add::<f32>);

// Test `i32`:
let args = ArgList::default().with_owned(25_i32).with_owned(75_i32);
let result = func.call(args).unwrap().unwrap_owned();
assert_eq!(result.try_take::<i32>().unwrap(), 100);

// Test `f32`:
let args = ArgList::default().with_owned(25.0_f32).with_owned(75.0_f32);
let result = func.call(args).unwrap().unwrap_owned();
assert_eq!(result.try_take::<f32>().unwrap(), 100.0);
fn add_2(a: i32, b: i32) -> i32 {
    a + b
}

fn add_3(a: i32, b: i32, c: i32) -> i32 {
    a + b + c
}

// Currently, `func` only supports two arguments.
let mut func = add_2.into_function();

// However, we can add an overload to handle three arguments as well.
func = func.with_overload(add_3);

// Test two arguments:
let args = ArgList::default().with_owned(25_i32).with_owned(75_i32);
let result = func.call(args).unwrap().unwrap_owned();
assert_eq!(result.try_take::<i32>().unwrap(), 100);

// Test three arguments:
let args = ArgList::default()
    .with_owned(25_i32)
    .with_owned(75_i32)
    .with_owned(100_i32);
let result = func.call(args).unwrap().unwrap_owned();
assert_eq!(result.try_take::<i32>().unwrap(), 200);

 fn add(a: i32, b: i32) -> i32 {
     a + b
 }

 fn sub(a: i32, b: i32) -> i32 {
     a - b
 }

 let mut func = add.into_function();

 // This will panic because the function already has an argument signature for `(i32, i32)`:
 func = func.with_overload(sub);
Source

pub fn try_with_overload<F: IntoFunction<'env, Marker>, Marker>( self, function: F, ) -> Result<Self, (Box<Self>, FunctionOverloadError)>

Attempt to add an overload to this function.

If the function, F, contains a signature already found in this function, an error will be returned along with the original function.

For a panicking version, see with_overload.

Source

pub fn call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a>

Call the function with the given arguments.

§Example
let c = 23;
let add = |a: i32, b: i32| -> i32 {
  a + b + c
};

let mut func = add.into_function().with_name("add");
let args = ArgList::new().with_owned(25_i32).with_owned(75_i32);
let result = func.call(args).unwrap().unwrap_owned();
assert_eq!(result.try_take::<i32>().unwrap(), 123);
§Errors

This method will return an error if the number of arguments provided does not match the number of arguments expected by the function’s FunctionInfo.

The function itself may also return any errors it needs to.

Source

pub fn info(&self) -> &FunctionInfo

Returns the function info.

Source

pub fn name(&self) -> Option<&Cow<'static, str>>

The name of the function.

For DynamicFunctions created using IntoFunction, the default name will always be the full path to the function as returned by core::any::type_name, unless the function is a closure, anonymous function, or function pointer, in which case the name will be None.

This can be overridden using with_name.

If the function was overloaded, it will retain its original name if it had one.

Source

pub fn is_overloaded(&self) -> bool

Returns true if the function is overloaded.

§Example
let add = (|a: i32, b: i32| a + b).into_function();
assert!(!add.is_overloaded());

let add = add.with_overload(|a: f32, b: f32| a + b);
assert!(add.is_overloaded());
Source

pub fn arg_count(&self) -> ArgCount

Returns the number of arguments the function expects.

For overloaded functions that can have a variable number of arguments, this will contain the full set of counts for all signatures.

§Example
let add = (|a: i32, b: i32| a + b).into_function();
assert!(add.arg_count().contains(2));

let add = add.with_overload(|a: f32, b: f32, c: f32| a + b + c);
assert!(add.arg_count().contains(2));
assert!(add.arg_count().contains(3));

Trait Implementations§

Source§

impl<'env> Clone for DynamicFunction<'env>

Source§

fn clone(&self) -> DynamicFunction<'env>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'env> Debug for DynamicFunction<'env>

Outputs the function’s signature.

This takes the format: DynamicFunction(fn {name}({arg1}: {type1}, {arg2}: {type2}, ...) -> {return_type}).

Names for arguments and the function itself are optional and will default to _ if not provided.

If the function is overloaded, the output will include the signatures of all overloads as a set. For example, DynamicFunction(fn add{(_: i32, _: i32) -> i32, (_: f32, _: f32) -> f32}).

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'env> From<DynamicFunction<'env>> for DynamicFunctionMut<'env>

Source§

fn from(function: DynamicFunction<'env>) -> Self

Converts to this type from the input type.
Source§

impl Function for DynamicFunction<'static>

Source§

fn name(&self) -> Option<&Cow<'static, str>>

The name of the function, if any. Read more
Source§

fn info(&self) -> &FunctionInfo

The FunctionInfo for this function.
Source§

fn reflect_call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a>

Call this function with the given arguments.
Source§

fn to_dynamic_function(&self) -> DynamicFunction<'static>

Creates a new DynamicFunction from this function.
Source§

fn arg_count(&self) -> ArgCount

Returns the number of arguments the function expects. Read more
Source§

impl<'env> IntoFunction<'env, ()> for DynamicFunction<'env>

Source§

fn into_function(self) -> DynamicFunction<'env>

Converts Self into a DynamicFunction.
Source§

impl<'env> IntoFunctionMut<'env, ()> for DynamicFunction<'env>

Source§

impl PartialReflect for DynamicFunction<'static>

Source§

fn get_represented_type_info(&self) -> Option<&'static TypeInfo>

Returns the TypeInfo of the type represented by this value. Read more
Source§

fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect>

Casts this type to a boxed, reflected value. Read more
Source§

fn as_partial_reflect(&self) -> &dyn PartialReflect

Casts this type to a reflected value. Read more
Source§

fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect

Casts this type to a mutable, reflected value. Read more
Source§

fn try_into_reflect( self: Box<Self>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>

Attempts to cast this type to a boxed, fully-reflected value.
Source§

fn try_as_reflect(&self) -> Option<&dyn Reflect>

Attempts to cast this type to a fully-reflected value.
Source§

fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect>

Attempts to cast this type to a mutable, fully-reflected value.
Source§

fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError>

Tries to apply a reflected value to this value. Read more
Source§

fn reflect_kind(&self) -> ReflectKind

Returns a zero-sized enumeration of “kinds” of type. Read more
Source§

fn reflect_ref(&self) -> ReflectRef<'_>

Returns an immutable enumeration of “kinds” of type. Read more
Source§

fn reflect_mut(&mut self) -> ReflectMut<'_>

Returns a mutable enumeration of “kinds” of type. Read more
Source§

fn reflect_owned(self: Box<Self>) -> ReflectOwned

Returns an owned enumeration of “kinds” of type. Read more
Source§

fn reflect_hash(&self) -> Option<u64>

Returns a hash of the value (which includes the type). Read more
Source§

fn reflect_partial_eq(&self, _value: &dyn PartialReflect) -> Option<bool>

Returns a “partial equality” comparison result. Read more
Source§

fn debug(&self, f: &mut Formatter<'_>) -> Result

Debug formatter for the value. Read more
Source§

fn is_dynamic(&self) -> bool

Indicates whether or not this type is a dynamic type. Read more
Source§

fn apply(&mut self, value: &dyn PartialReflect)

Applies a reflected value to this value. Read more
Source§

fn to_dynamic(&self) -> Box<dyn PartialReflect>

Converts this reflected value into its dynamic representation based on its kind. Read more
Source§

fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>

Attempts to clone Self using reflection. Read more
Source§

fn reflect_clone_and_take<T: 'static>(&self) -> Result<T, ReflectCloneError>
where Self: TypePath + Sized,

For a type implementing PartialReflect, combines reflect_clone and take in a useful fashion, automatically constructing an appropriate ReflectCloneError if the downcast fails. Read more
Source§

impl<'env> TypePath for DynamicFunction<'env>
where DynamicFunction<'env>: 'static,

Source§

fn type_path() -> &'static str

Returns the fully qualified path of the underlying type. Read more
Source§

fn short_type_path() -> &'static str

Returns a short, pretty-print enabled path to the type. Read more
Source§

fn type_ident() -> Option<&'static str>

Returns the name of the type, or None if it is anonymous. Read more
Source§

fn crate_name() -> Option<&'static str>

Returns the name of the crate the type is in, or None if it is anonymous. Read more
Source§

fn module_path() -> Option<&'static str>

Returns the path to the module the type is in, or None if it is anonymous. Read more

Auto Trait Implementations§

§

impl<'env> Freeze for DynamicFunction<'env>

§

impl<'env> !RefUnwindSafe for DynamicFunction<'env>

§

impl<'env> Send for DynamicFunction<'env>

§

impl<'env> Sync for DynamicFunction<'env>

§

impl<'env> Unpin for DynamicFunction<'env>

§

impl<'env> !UnwindSafe for DynamicFunction<'env>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynamicTypePath for T
where T: TypePath,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,