Skip to main content

bevy_reflect_derive/
trait_reflection.rs

1use bevy_macro_utils::fq_std::{FQClone, FQOption, FQResult};
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::{parse::Parse, parse_macro_input, Attribute, ItemTrait, Token};
5
6pub(crate) struct TraitInfo {
7    item_trait: ItemTrait,
8}
9
10impl Parse for TraitInfo {
11    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
12        let attrs = input.call(Attribute::parse_outer)?;
13        let lookahead = input.lookahead1();
14        if lookahead.peek(::syn::token::PubToken![pub]) || lookahead.peek(::syn::token::TraitToken![trait]) {
15            let mut item_trait: ItemTrait = input.parse()?;
16            item_trait.attrs = attrs;
17            Ok(TraitInfo { item_trait })
18        } else {
19            Err(lookahead.error())
20        }
21    }
22}
23
24/// A trait attribute macro that allows a reflected type to be downcast to a trait object.
25///
26/// This generates a struct that takes the form `ReflectMyTrait`. An instance of this struct can then be
27/// used to perform the conversion.
28pub(crate) fn reflect_trait(_args: &TokenStream, input: TokenStream) -> TokenStream {
29    let trait_info = match ::syn::parse::<TraitInfo>(input) {
    ::syn::__private::Ok(data) => data,
    ::syn::__private::Err(err) => {
        return ::syn::__private::TokenStream::from(err.to_compile_error());
    }
}parse_macro_input!(input as TraitInfo);
30    let item_trait = &trait_info.item_trait;
31    let trait_ident = &item_trait.ident;
32    let trait_vis = &item_trait.vis;
33    let reflect_trait_ident = crate::ident::get_reflect_ident(&item_trait.ident.to_string());
34    let bevy_reflect_path = crate::meta::get_bevy_reflect_path();
35
36    let struct_doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" A type generated by the #[reflect_trait] macro for the `{0}` trait.\n\n This allows casting from `dyn Reflect` to `dyn {0}`.",
                trait_ident))
    })format!(
37        " A type generated by the #[reflect_trait] macro for the `{trait_ident}` trait.\n\n This allows casting from `dyn Reflect` to `dyn {trait_ident}`.",
38    );
39    let get_doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" Downcast a `&dyn Reflect` type to `&dyn {0}`.\n\n If the type cannot be downcast, `None` is returned.",
                trait_ident))
    })format!(
40        " Downcast a `&dyn Reflect` type to `&dyn {trait_ident}`.\n\n If the type cannot be downcast, `None` is returned.",
41    );
42    let get_mut_doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" Downcast a `&mut dyn Reflect` type to `&mut dyn {0}`.\n\n If the type cannot be downcast, `None` is returned.",
                trait_ident))
    })format!(
43        " Downcast a `&mut dyn Reflect` type to `&mut dyn {trait_ident}`.\n\n If the type cannot be downcast, `None` is returned.",
44    );
45    let get_box_doc = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" Downcast a `Box<dyn Reflect>` type to `Box<dyn {0}>`.\n\n If the type cannot be downcast, this will return `Err(Box<dyn Reflect>)`.",
                trait_ident))
    })format!(
46        " Downcast a `Box<dyn Reflect>` type to `Box<dyn {trait_ident}>`.\n\n If the type cannot be downcast, this will return `Err(Box<dyn Reflect>)`.",
47    );
48
49    TokenStream::from({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&item_trait, &mut _s);
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&struct_doc, &mut _s);
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "derive");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&FQClone, &mut _s);
                    _s
                });
            _s
        });
    ::quote::ToTokens::to_tokens(&trait_vis, &mut _s);
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&reflect_trait_ident, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "get_func");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQOption, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "get_mut_func");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQOption, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "get_boxed_func");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__macro_exports");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "alloc_utils");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Box");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQResult, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__macro_exports");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "alloc_utils");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Box");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__macro_exports");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "alloc_utils");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Box");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Reflect");
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&reflect_trait_ident, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&get_doc, &mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "get");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "reflect_value");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_lifetime(&mut _s, "\'a");
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQOption, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get_func");
                            _s
                        });
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&get_mut_doc, &mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "get_mut");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "reflect_value");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_lifetime(&mut _s, "\'a");
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQOption, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'a");
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get_mut_func");
                            _s
                        });
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&get_box_doc, &mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "get_boxed");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "reflect_value");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__macro_exports");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "alloc_utils");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Box");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dyn");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Reflect");
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&FQResult, &mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__macro_exports");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "alloc_utils");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Box");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__macro_exports");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "alloc_utils");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Box");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dyn");
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Reflect");
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get_boxed_func");
                            _s
                        });
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "T");
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
    ::quote::__private::push_add(&mut _s);
    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Reflect");
    ::quote::__private::push_gt(&mut _s);
    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "FromType");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "T");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&reflect_trait_ident, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_type");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "get_func");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "dyn");
                                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Reflect");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "downcast_ref");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "T");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                                            _s
                                        });
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "map");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_ident(&mut _s, "as");
                                            ::quote::__private::push_and(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "dyn");
                                            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get_mut_func");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "dyn");
                                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Reflect");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "downcast_mut");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "T");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                                            _s
                                        });
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "map");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_ident(&mut _s, "as");
                                            ::quote::__private::push_and(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "mut");
                                            ::quote::__private::push_ident(&mut _s, "dyn");
                                            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get_boxed_func");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "dyn");
                                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Reflect");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "downcast");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "T");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "reflect_value");
                                            _s
                                        });
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "map");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "value");
                                            ::quote::__private::push_ident(&mut _s, "as");
                                            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "__macro_exports");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "alloc_utils");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "Box");
                                            ::quote::__private::push_lt(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "dyn");
                                            ::quote::ToTokens::to_tokens(&trait_ident, &mut _s);
                                            ::quote::__private::push_gt(&mut _s);
                                            _s
                                        });
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
50        #item_trait
51
52        #[doc = #struct_doc]
53        #[derive(#FQClone)]
54        #trait_vis struct #reflect_trait_ident {
55            get_func: fn(&dyn #bevy_reflect_path::Reflect) -> #FQOption<&dyn #trait_ident>,
56            get_mut_func: fn(&mut dyn #bevy_reflect_path::Reflect) -> #FQOption<&mut dyn #trait_ident>,
57            get_boxed_func: fn(#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>>,
58        }
59
60        impl #reflect_trait_ident {
61            #[doc = #get_doc]
62            pub fn get<'a>(&self, reflect_value: &'a dyn #bevy_reflect_path::Reflect) -> #FQOption<&'a dyn #trait_ident> {
63                (self.get_func)(reflect_value)
64            }
65
66            #[doc = #get_mut_doc]
67            pub fn get_mut<'a>(&self, reflect_value: &'a mut dyn #bevy_reflect_path::Reflect) -> #FQOption<&'a mut dyn #trait_ident> {
68                (self.get_mut_func)(reflect_value)
69            }
70
71            #[doc = #get_box_doc]
72            pub fn get_boxed(&self, reflect_value: #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>) -> #FQResult<#bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>, #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::Reflect>> {
73                (self.get_boxed_func)(reflect_value)
74            }
75        }
76
77        impl<T: #trait_ident + #bevy_reflect_path::Reflect> #bevy_reflect_path::FromType<T> for #reflect_trait_ident {
78            fn from_type() -> Self {
79                Self {
80                    get_func: |reflect_value| {
81                        <dyn #bevy_reflect_path::Reflect>::downcast_ref::<T>(reflect_value).map(|value| value as &dyn #trait_ident)
82                    },
83                    get_mut_func: |reflect_value| {
84                        <dyn #bevy_reflect_path::Reflect>::downcast_mut::<T>(reflect_value).map(|value| value as &mut dyn #trait_ident)
85                    },
86                    get_boxed_func: |reflect_value| {
87                        <dyn #bevy_reflect_path::Reflect>::downcast::<T>(reflect_value).map(|value| value as #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #trait_ident>)
88                    }
89                }
90            }
91        }
92    })
93}