Path: blob/main/crates/bevy_reflect/src/func/function.rs
6599 views
use crate::{1func::{2args::{ArgCount, ArgList},3DynamicFunction, FunctionInfo, FunctionResult,4},5PartialReflect,6};7use alloc::borrow::Cow;8use core::fmt::Debug;910/// A trait used to power [function-like] operations via [reflection].11///12/// This trait allows types to be called like regular functions13/// with [`Reflect`]-based [arguments] and return values.14///15/// By default, this trait is currently only implemented for [`DynamicFunction`],16/// however, it is possible to implement this trait for custom function-like types.17///18/// # Example19///20/// ```21/// # use bevy_reflect::func::{IntoFunction, ArgList, Function};22/// fn add(a: i32, b: i32) -> i32 {23/// a + b24/// }25///26/// let func: Box<dyn Function> = Box::new(add.into_function());27/// let args = ArgList::new().with_owned(25_i32).with_owned(75_i32);28/// let value = func.reflect_call(args).unwrap().unwrap_owned();29/// assert_eq!(value.try_take::<i32>().unwrap(), 100);30/// ```31///32/// [function-like]: crate::func33/// [reflection]: crate::Reflect34/// [`Reflect`]: crate::Reflect35/// [arguments]: crate::func::args36/// [`DynamicFunction`]: crate::func::DynamicFunction37pub trait Function: PartialReflect + Debug {38/// The name of the function, if any.39///40/// For [`DynamicFunctions`] created using [`IntoFunction`],41/// the default name will always be the full path to the function as returned by [`core::any::type_name`],42/// unless the function is a closure, anonymous function, or function pointer,43/// in which case the name will be `None`.44///45/// [`DynamicFunctions`]: crate::func::DynamicFunction46/// [`IntoFunction`]: crate::func::IntoFunction47fn name(&self) -> Option<&Cow<'static, str>>;4849/// Returns the number of arguments the function expects.50///51/// For [overloaded] functions that can have a variable number of arguments,52/// this will contain the full set of counts for all signatures.53///54/// [overloaded]: crate::func#overloading-functions55fn arg_count(&self) -> ArgCount {56self.info().arg_count()57}5859/// The [`FunctionInfo`] for this function.60fn info(&self) -> &FunctionInfo;6162/// Call this function with the given arguments.63fn reflect_call<'a>(&self, args: ArgList<'a>) -> FunctionResult<'a>;6465/// Creates a new [`DynamicFunction`] from this function.66fn to_dynamic_function(&self) -> DynamicFunction<'static>;67}6869#[cfg(test)]70mod tests {71use super::*;72use crate::func::IntoFunction;73use alloc::boxed::Box;7475#[test]76fn should_call_dyn_function() {77fn add(a: i32, b: i32) -> i32 {78a + b79}8081let func: Box<dyn Function> = Box::new(add.into_function());82let args = ArgList::new().with_owned(25_i32).with_owned(75_i32);83let value = func.reflect_call(args).unwrap().unwrap_owned();84assert_eq!(value.try_take::<i32>().unwrap(), 100);85}86}878889