Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/func/args/from_arg.rs
6600 views
1
use crate::func::args::{Arg, ArgError};
2
use 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
20
pub 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.
36
impl<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.
44
impl<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
58
macro_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
89
pub(crate) use impl_from_arg;
90
91