bevy_reflect/func/args/
from_arg.rs

1use crate::func::args::{Arg, ArgError};
2use crate::{Reflect, TypePath};
3
4/// A trait for types that can be created from an [`Arg`].
5///
6/// This trait exists so that types can be automatically converted into an [`Arg`]
7/// so they can be put into an [`ArgList`] and passed to a [`DynamicFunction`] or
8/// [`DynamicFunctionMut`].
9///
10/// This trait is used instead of a blanket [`From`] implementation due to coherence issues:
11/// we can't implement `From<T>` for both `T` and `&T`/`&mut T`.
12///
13/// This trait is automatically implemented for non-reference types when using the `Reflect`
14/// [derive macro]. Blanket impls cover `&T` and `&mut T`.
15///
16/// [`ArgList`]: crate::func::args::ArgList
17/// [`DynamicFunction`]: crate::func::DynamicFunction
18/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
19/// [derive macro]: derive@crate::Reflect
20pub trait FromArg {
21    /// The type to convert into.
22    ///
23    /// This should almost always be the same as `Self`, but with the lifetime `'a`.
24    ///
25    /// The reason we use a separate associated type is to allow for the lifetime
26    /// to be tied to the argument, rather than the type itself.
27    type This<'a>;
28
29    /// Creates an item from an argument.
30    ///
31    /// The argument must be of the expected type and ownership.
32    fn from_arg(arg: Arg<'_>) -> Result<Self::This<'_>, ArgError>;
33}
34
35// Blanket impl.
36impl<T: Reflect + TypePath> FromArg for &'static T {
37    type This<'a> = &'a T;
38    fn from_arg(arg: Arg<'_>) -> Result<Self::This<'_>, ArgError> {
39        arg.take_ref()
40    }
41}
42
43// Blanket impl.
44impl<T: Reflect + TypePath> FromArg for &'static mut T {
45    type This<'a> = &'a mut T;
46    fn from_arg(arg: Arg<'_>) -> Result<Self::This<'_>, ArgError> {
47        arg.take_mut()
48    }
49}
50
51/// Implements the [`FromArg`] trait for the given type.
52///
53/// This will implement it for `$ty`, `&$ty`, and `&mut $ty`.
54///
55/// See [`impl_function_traits`] for details on syntax.
56///
57/// [`impl_function_traits`]: crate::func::macros::impl_function_traits
58macro_rules! impl_from_arg {
59    (
60        $ty: ty
61        $(;
62            < $($T: ident $(: $T1: tt $(+ $T2: tt)*)?),* >
63        )?
64        $(
65            [ $(const $N: ident : $size: ident),* ]
66        )?
67        $(
68            where $($U: ty $(: $U1: tt $(+ $U2: tt)*)?),*
69        )?
70    ) => {
71        impl <
72            $($($T $(: $T1 $(+ $T2)*)?),*)?
73            $(, $(const $N : $size),*)?
74        > $crate::func::args::FromArg for $ty
75        $(
76            where $($U $(: $U1 $(+ $U2)*)?),*
77        )?
78        {
79            type This<'from_arg> = $ty;
80            fn from_arg(arg: $crate::func::args::Arg<'_>) ->
81                Result<Self::This<'_>, $crate::func::args::ArgError>
82            {
83                arg.take_owned()
84            }
85        }
86    };
87}
88
89pub(crate) use impl_from_arg;