Path: blob/main/crates/bevy_reflect/src/func/into_function.rs
6599 views
use crate::func::{DynamicFunction, ReflectFn, TypedFunction};12/// A trait for types that can be converted into a [`DynamicFunction`].3///4/// This trait is automatically implemented for any type that implements5/// [`ReflectFn`] and [`TypedFunction`].6///7/// See the [module-level documentation] for more information.8///9/// # Trait Parameters10///11/// This trait has a `Marker` type parameter that is used to get around issues with12/// [unconstrained type parameters] when defining impls with generic arguments or return types.13/// This `Marker` can be any type, provided it doesn't conflict with other implementations.14///15/// Additionally, it has a lifetime parameter, `'env`, that is used to bound the lifetime of the function.16/// For named functions and some closures, this will end up just being `'static`,17/// however, closures that borrow from their environment will have a lifetime bound to that environment.18///19/// [module-level documentation]: crate::func20/// [unconstrained type parameters]: https://doc.rust-lang.org/error_codes/E0207.html21pub trait IntoFunction<'env, Marker> {22/// Converts [`Self`] into a [`DynamicFunction`].23fn into_function(self) -> DynamicFunction<'env>;24}2526impl<'env, F, Marker1, Marker2> IntoFunction<'env, (Marker1, Marker2)> for F27where28F: ReflectFn<'env, Marker1> + TypedFunction<Marker2> + Send + Sync + 'env,29{30fn into_function(self) -> DynamicFunction<'env> {31DynamicFunction::new(move |args| self.reflect_call(args), Self::function_info())32}33}3435#[cfg(test)]36mod tests {37use super::*;38use crate::func::ArgList;3940#[test]41fn should_create_dynamic_function_from_closure() {42let c = 23;43let func = (|a: i32, b: i32| a + b + c).into_function();44let args = ArgList::new().with_owned(25_i32).with_owned(75_i32);45let result = func.call(args).unwrap().unwrap_owned();46assert_eq!(result.try_downcast_ref::<i32>(), Some(&123));47}4849#[test]50fn should_create_dynamic_function_from_function() {51fn add(a: i32, b: i32) -> i32 {52a + b53}5455let func = add.into_function();56let args = ArgList::new().with_owned(25_i32).with_owned(75_i32);57let result = func.call(args).unwrap().unwrap_owned();58assert_eq!(result.try_downcast_ref::<i32>(), Some(&100));59}6061#[test]62fn should_default_closure_name_to_none() {63let c = 23;64let func = (|a: i32, b: i32| a + b + c).into_function();65assert!(func.name().is_none());66}67}686970