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