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