bevy_reflect_derive/impls/
opaque.rs1use crate::{
2 impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
3 where_clause_options::WhereClauseOptions,
4 ReflectMeta,
5};
6use bevy_macro_utils::fq_std::{FQClone, FQOption, FQResult};
7use quote::quote;
8
9pub(crate) fn impl_opaque(meta: &ReflectMeta) -> proc_macro2::TokenStream {
11 let bevy_reflect_path = meta.bevy_reflect_path();
12 let type_path = meta.type_path();
13
14 #[cfg(feature = "documentation")]
15 let with_docs = {
16 let doc = quote::ToTokens::to_token_stream(meta.doc());
17 Some(quote!(.with_docs(#doc)))
18 };
19 #[cfg(not(feature = "documentation"))]
20 let with_docs: Option<proc_macro2::TokenStream> = None;
21
22 let where_clause_options = WhereClauseOptions::new(meta);
23 let typed_impl = impl_typed(
24 &where_clause_options,
25 quote! {
26 let info = #bevy_reflect_path::OpaqueInfo::new::<Self>() #with_docs;
27 #bevy_reflect_path::TypeInfo::Opaque(info)
28 },
29 );
30
31 let type_path_impl = impl_type_path(meta);
32 let full_reflect_impl = impl_full_reflect(&where_clause_options);
33 let common_methods = common_partial_reflect_methods(meta, || None, || None);
34 let clone_fn = meta.attrs().get_clone_impl(bevy_reflect_path);
35
36 let apply_impl = if let Some(remote_ty) = meta.remote_ty() {
37 let ty = remote_ty.type_path();
38 quote! {
39 if let #FQOption::Some(value) = <dyn #bevy_reflect_path::PartialReflect>::try_downcast_ref::<#ty>(value) {
40 *self = Self(#FQClone::clone(value));
41 return #FQResult::Ok(());
42 }
43 }
44 } else {
45 quote! {
46 if let #FQOption::Some(value) = <dyn #bevy_reflect_path::PartialReflect>::try_downcast_ref::<Self>(value) {
47 *self = #FQClone::clone(value);
48 return #FQResult::Ok(());
49 }
50 }
51 };
52
53 #[cfg(not(feature = "functions"))]
54 let function_impls = None::<proc_macro2::TokenStream>;
55 #[cfg(feature = "functions")]
56 let function_impls = crate::impls::impl_function_traits(&where_clause_options);
57
58 #[cfg(not(feature = "auto_register"))]
59 let auto_register = None::<proc_macro2::TokenStream>;
60 #[cfg(feature = "auto_register")]
61 let auto_register = crate::impls::reflect_auto_registration(meta);
62
63 let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
64 let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
65 let get_type_registration_impl = meta.get_type_registration(&where_clause_options);
66
67 quote! {
68 #get_type_registration_impl
69
70 #type_path_impl
71
72 #typed_impl
73
74 #full_reflect_impl
75
76 #function_impls
77
78 #auto_register
79
80 impl #impl_generics #bevy_reflect_path::PartialReflect for #type_path #ty_generics #where_reflect_clause {
81 #[inline]
82 fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
83 #FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
84 }
85
86 #[inline]
87 fn to_dynamic(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
88 #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#FQClone::clone(self))
89 }
90
91 #[inline]
92 fn try_apply(
93 &mut self,
94 value: &dyn #bevy_reflect_path::PartialReflect
95 ) -> #FQResult<(), #bevy_reflect_path::ApplyError> {
96 #apply_impl
97
98 #FQResult::Err(
99 #bevy_reflect_path::ApplyError::MismatchedTypes {
100 from_type: ::core::convert::Into::into(#bevy_reflect_path::DynamicTypePath::reflect_type_path(value)),
101 to_type: ::core::convert::Into::into(<Self as #bevy_reflect_path::TypePath>::type_path()),
102 }
103 )
104 }
105
106 #[inline]
107 fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
108 #bevy_reflect_path::ReflectKind::Opaque
109 }
110
111 #[inline]
112 fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
113 #bevy_reflect_path::ReflectRef::Opaque(self)
114 }
115
116 #[inline]
117 fn reflect_mut(&mut self) -> #bevy_reflect_path::ReflectMut {
118 #bevy_reflect_path::ReflectMut::Opaque(self)
119 }
120
121 #[inline]
122 fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
123 #bevy_reflect_path::ReflectOwned::Opaque(self)
124 }
125
126 #common_methods
127
128 #clone_fn
129 }
130 }
131}