bevy_reflect_derive/
lib.rs

1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2
3//! This crate contains macros used by Bevy's `Reflect` API.
4//!
5//! The main export of this crate is the derive macro for [`Reflect`]. This allows
6//! types to easily implement `Reflect` along with other `bevy_reflect` traits,
7//! such as `Struct`, `GetTypeRegistration`, and more— all with a single derive!
8//!
9//! Some other noteworthy exports include the derive macros for [`FromReflect`] and
10//! [`TypePath`], as well as the [`reflect_trait`] attribute macro.
11//!
12//! [`Reflect`]: crate::derive_reflect
13//! [`FromReflect`]: crate::derive_from_reflect
14//! [`TypePath`]: crate::derive_type_path
15//! [`reflect_trait`]: macro@reflect_trait
16
17extern crate proc_macro;
18
19mod attribute_parser;
20mod container_attributes;
21mod custom_attributes;
22mod derive_data;
23#[cfg(feature = "documentation")]
24mod documentation;
25mod enum_utility;
26mod field_attributes;
27mod from_reflect;
28mod generics;
29mod ident;
30mod impls;
31mod meta;
32mod reflect_opaque;
33mod registration;
34mod remote;
35mod result_sifter;
36mod serialization;
37mod string_expr;
38mod struct_utility;
39mod trait_reflection;
40mod type_path;
41mod where_clause_options;
42
43use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
44use container_attributes::ContainerAttributes;
45use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
46use proc_macro::TokenStream;
47use quote::quote;
48use reflect_opaque::ReflectOpaqueDef;
49use syn::{parse_macro_input, DeriveInput};
50use type_path::NamedTypePathDef;
51
52pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";
53pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
54pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
55
56/// Used both for [`impl_reflect`] and [`derive_reflect`].
57///
58/// [`impl_reflect`]: macro@impl_reflect
59/// [`derive_reflect`]: derive_reflect()
60fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {
61    let derive_data = match ReflectDerive::from_input(
62        &ast,
63        ReflectProvenance {
64            source,
65            trait_: ReflectTraitToImpl::Reflect,
66        },
67    ) {
68        Ok(data) => data,
69        Err(err) => return err.into_compile_error().into(),
70    };
71
72    let assertions = impls::impl_assertions(&derive_data);
73
74    let (reflect_impls, from_reflect_impl) = match derive_data {
75        ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
76            impls::impl_struct(&struct_data),
77            if struct_data.meta().from_reflect().should_auto_derive() {
78                Some(from_reflect::impl_struct(&struct_data))
79            } else {
80                None
81            },
82        ),
83        ReflectDerive::TupleStruct(struct_data) => (
84            impls::impl_tuple_struct(&struct_data),
85            if struct_data.meta().from_reflect().should_auto_derive() {
86                Some(from_reflect::impl_tuple_struct(&struct_data))
87            } else {
88                None
89            },
90        ),
91        ReflectDerive::Enum(enum_data) => (
92            impls::impl_enum(&enum_data),
93            if enum_data.meta().from_reflect().should_auto_derive() {
94                Some(from_reflect::impl_enum(&enum_data))
95            } else {
96                None
97            },
98        ),
99        ReflectDerive::Opaque(meta) => (
100            impls::impl_opaque(&meta),
101            if meta.from_reflect().should_auto_derive() {
102                Some(from_reflect::impl_opaque(&meta))
103            } else {
104                None
105            },
106        ),
107    };
108
109    TokenStream::from(quote! {
110        const _: () = {
111            #reflect_impls
112
113            #from_reflect_impl
114
115            #assertions
116        };
117    })
118}
119
120/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.
121///
122/// This macro can be used on all structs and enums (unions are not supported).
123/// It will automatically generate implementations for `Reflect`, `Typed`, `GetTypeRegistration`, and `FromReflect`.
124/// And, depending on the item's structure, will either implement `Struct`, `TupleStruct`, or `Enum`.
125///
126/// See the [`FromReflect`] derive macro for more information on how to customize the `FromReflect` implementation.
127///
128/// # Container Attributes
129///
130/// This macro comes with some helper attributes that can be added to the container item
131/// in order to provide additional functionality or alter the generated implementations.
132///
133/// In addition to those listed, this macro can also use the attributes for [`TypePath`] derives.
134///
135/// ## `#[reflect(Ident)]`
136///
137/// The `#[reflect(Ident)]` attribute is used to add type data registrations to the `GetTypeRegistration`
138/// implementation corresponding to the given identifier, prepended by `Reflect`.
139///
140/// For example, `#[reflect(Foo, Bar)]` would add two registrations:
141/// one for `ReflectFoo` and another for `ReflectBar`.
142/// This assumes these types are indeed in-scope wherever this macro is called.
143///
144/// This is often used with traits that have been marked by the [`#[reflect_trait]`](macro@reflect_trait)
145/// macro in order to register the type's implementation of that trait.
146///
147/// ### Default Registrations
148///
149/// The following types are automatically registered when deriving `Reflect`:
150///
151/// * `ReflectFromReflect` (unless opting out of `FromReflect`)
152/// * `SerializationData`
153/// * `ReflectFromPtr`
154///
155/// ### Special Identifiers
156///
157/// There are a few "special" identifiers that work a bit differently:
158///
159/// * `#[reflect(Debug)]` will force the implementation of `Reflect::reflect_debug` to rely on
160///   the type's [`Debug`] implementation.
161///   A custom implementation may be provided using `#[reflect(Debug(my_debug_func))]` where
162///   `my_debug_func` is the path to a function matching the signature:
163///   `(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result`.
164/// * `#[reflect(PartialEq)]` will force the implementation of `Reflect::reflect_partial_eq` to rely on
165///   the type's [`PartialEq`] implementation.
166///   A custom implementation may be provided using `#[reflect(PartialEq(my_partial_eq_func))]` where
167///   `my_partial_eq_func` is the path to a function matching the signature:
168///   `(&self, value: &dyn #bevy_reflect_path::Reflect) -> bool`.
169/// * `#[reflect(Hash)]` will force the implementation of `Reflect::reflect_hash` to rely on
170///   the type's [`Hash`] implementation.
171///   A custom implementation may be provided using `#[reflect(Hash(my_hash_func))]` where
172///   `my_hash_func` is the path to a function matching the signature: `(&self) -> u64`.
173/// * `#[reflect(Default)]` will register the `ReflectDefault` type data as normal.
174///   However, it will also affect how certain other operations are performed in order
175///   to improve performance and/or robustness.
176///   An example of where this is used is in the [`FromReflect`] derive macro,
177///   where adding this attribute will cause the `FromReflect` implementation to create
178///   a base value using its [`Default`] implementation avoiding issues with ignored fields
179///   (for structs and tuple structs only).
180///
181/// ## `#[reflect(opaque)]`
182///
183/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,
184/// hiding its structure and fields from the reflection API.
185/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.
186///
187/// Furthermore, it requires that the type implements [`Clone`].
188/// If planning to serialize this type using the reflection serializers,
189/// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well.
190///
191/// ## `#[reflect(from_reflect = false)]`
192///
193/// This attribute will opt-out of the default `FromReflect` implementation.
194///
195/// This is useful for when a type can't or shouldn't implement `FromReflect`,
196/// or if a manual implementation is desired.
197///
198/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered.
199///
200/// ## `#[reflect(type_path = false)]`
201///
202/// This attribute will opt-out of the default `TypePath` implementation.
203///
204/// This is useful for when a type can't or shouldn't implement `TypePath`,
205/// or if a manual implementation is desired.
206///
207/// ## `#[reflect(no_field_bounds)]`
208///
209/// This attribute will opt-out of the default trait bounds added to all field types
210/// for the generated reflection trait impls.
211///
212/// Normally, all fields will have the bounds `TypePath`, and either `FromReflect` or `Reflect`
213/// depending on if `#[reflect(from_reflect = false)]` is used.
214/// However, this might not always be desirable, and so this attribute may be used to remove those bounds.
215///
216/// ### Example
217///
218/// If a type is recursive the default bounds will cause an overflow error when building:
219///
220/// ```ignore (bevy_reflect is not accessible from this crate)
221/// #[derive(Reflect)] // ERROR: overflow evaluating the requirement `Foo: FromReflect`
222/// struct Foo {
223///   foo: Vec<Foo>,
224/// }
225///
226/// // Generates a where clause like:
227/// // impl bevy_reflect::Reflect for Foo
228/// // where
229/// //   Self: Any + Send + Sync,
230/// //   Vec<Foo>: FromReflect + TypePath,
231/// ```
232///
233/// In this case, `Foo` is given the bounds `Vec<Foo>: FromReflect + TypePath`,
234/// which requires that `Foo` implements `FromReflect`,
235/// which requires that `Vec<Foo>` implements `FromReflect`,
236/// and so on, resulting in the error.
237///
238/// To fix this, we can add `#[reflect(no_field_bounds)]` to `Foo` to remove the bounds on `Vec<Foo>`:
239///
240/// ```ignore (bevy_reflect is not accessible from this crate)
241/// #[derive(Reflect)]
242/// #[reflect(no_field_bounds)]
243/// struct Foo {
244///   foo: Vec<Foo>,
245/// }
246///
247/// // Generates a where clause like:
248/// // impl bevy_reflect::Reflect for Foo
249/// // where
250/// //   Self: Any + Send + Sync,
251/// ```
252///
253/// ## `#[reflect(where T: Trait, U::Assoc: Trait, ...)]`
254///
255/// This attribute can be used to add additional bounds to the generated reflection trait impls.
256///
257/// This is useful for when a type needs certain bounds only applied to the reflection impls
258/// that are not otherwise automatically added by the derive macro.
259///
260/// ### Example
261///
262/// In the example below, we want to enforce that `T::Assoc: List` is required in order for
263/// `Foo<T>` to be reflectable, but we don't want it to prevent `Foo<T>` from being used
264/// in places where `T::Assoc: List` is not required.
265///
266/// ```ignore
267/// trait Trait {
268///   type Assoc;
269/// }
270///
271/// #[derive(Reflect)]
272/// #[reflect(where T::Assoc: List)]
273/// struct Foo<T: Trait> where T::Assoc: Default {
274///   value: T::Assoc,
275/// }
276///
277/// // Generates a where clause like:
278/// //
279/// // impl<T: Trait> bevy_reflect::Reflect for Foo<T>
280/// // where
281/// //   Self: Any + Send + Sync,
282/// //   T::Assoc: Default,
283/// //   T: TypePath,
284/// //   T::Assoc: FromReflect + TypePath,
285/// //   T::Assoc: List,
286/// // {/* ... */}
287/// ```
288///
289/// ## `#[reflect(@...)]`
290///
291/// This attribute can be used to register custom attributes to the type's `TypeInfo`.
292///
293/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.
294///
295/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
296/// If two attributes of the same type are registered, the last one will overwrite the first.
297///
298/// ### Example
299///
300/// ```ignore
301/// #[derive(Reflect)]
302/// struct Required;
303///
304/// #[derive(Reflect)]
305/// struct EditorTooltip(String);
306///
307/// impl EditorTooltip {
308///   fn new(text: &str) -> Self {
309///     Self(text.to_string())
310///   }
311/// }
312///
313/// #[derive(Reflect)]
314/// // Specify a "required" status and tooltip:
315/// #[reflect(@Required, @EditorTooltip::new("An ID is required!"))]
316/// struct Id(u8);
317/// ```
318///
319/// # Field Attributes
320///
321/// Along with the container attributes, this macro comes with some attributes that may be applied
322/// to the contained fields themselves.
323///
324/// ## `#[reflect(ignore)]`
325///
326/// This attribute simply marks a field to be ignored by the reflection API.
327///
328/// This allows fields to completely opt-out of reflection,
329/// which may be useful for maintaining invariants, keeping certain data private,
330/// or allowing the use of types that do not implement `Reflect` within the container.
331///
332/// ## `#[reflect(skip_serializing)]`
333///
334/// This works similar to `#[reflect(ignore)]`, but rather than opting out of _all_ of reflection,
335/// it simply opts the field out of both serialization and deserialization.
336/// This can be useful when a field should be accessible via reflection, but may not make
337/// sense in a serialized form, such as computed data.
338///
339/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,
340/// which will be used by the reflection serializers to determine whether or not the field is serializable.
341///
342/// ## `#[reflect(@...)]`
343///
344/// This attribute can be used to register custom attributes to the field's `TypeInfo`.
345///
346/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.
347///
348/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
349/// If two attributes of the same type are registered, the last one will overwrite the first.
350///
351/// ### Example
352///
353/// ```ignore
354/// #[derive(Reflect)]
355/// struct EditorTooltip(String);
356///
357/// impl EditorTooltip {
358///   fn new(text: &str) -> Self {
359///     Self(text.to_string())
360///   }
361/// }
362///
363/// #[derive(Reflect)]
364/// struct Slider {
365///   // Specify a custom range and tooltip:
366///   #[reflect(@0.0..=1.0, @EditorTooltip::new("Must be between 0 and 1"))]
367///   value: f32,
368/// }
369/// ```
370///
371/// [`reflect_trait`]: macro@reflect_trait
372#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]
373pub fn derive_reflect(input: TokenStream) -> TokenStream {
374    let ast = parse_macro_input!(input as DeriveInput);
375    match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
376}
377
378/// Derives the `FromReflect` trait.
379///
380/// # Field Attributes
381///
382/// ## `#[reflect(ignore)]`
383///
384/// The `#[reflect(ignore)]` attribute is shared with the [`#[derive(Reflect)]`](Reflect) macro and has much of the same
385/// functionality in that it denotes that a field will be ignored by the reflection API.
386///
387/// The only major difference is that using it with this derive requires that the field implements [`Default`].
388/// Without this requirement, there would be no way for `FromReflect` to automatically construct missing fields
389/// that have been ignored.
390///
391/// ## `#[reflect(default)]`
392///
393/// If a field cannot be read, this attribute specifies a default value to be used in its place.
394///
395/// By default, this attribute denotes that the field's type implements [`Default`].
396/// However, it can also take in a path string to a user-defined function that will return the default value.
397/// This takes the form: `#[reflect(default = "path::to::my_function")]` where `my_function` is a parameterless
398/// function that must return some default value for the type.
399///
400/// Specifying a custom default can be used to give different fields their own specialized defaults,
401/// or to remove the `Default` requirement on fields marked with `#[reflect(ignore)]`.
402/// Additionally, either form of this attribute can be used to fill in fields that are simply missing,
403/// such as when converting a partially-constructed dynamic type to a concrete one.
404#[proc_macro_derive(FromReflect, attributes(reflect))]
405pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
406    let ast = parse_macro_input!(input as DeriveInput);
407
408    let derive_data = match ReflectDerive::from_input(
409        &ast,
410        ReflectProvenance {
411            source: ReflectImplSource::DeriveLocalType,
412            trait_: ReflectTraitToImpl::FromReflect,
413        },
414    ) {
415        Ok(data) => data,
416        Err(err) => return err.into_compile_error().into(),
417    };
418
419    let from_reflect_impl = match derive_data {
420        ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => {
421            from_reflect::impl_struct(&struct_data)
422        }
423        ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),
424        ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),
425        ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),
426    };
427
428    TokenStream::from(quote! {
429        const _: () = {
430            #from_reflect_impl
431        };
432    })
433}
434
435/// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`].
436///
437/// # Container Attributes
438///
439/// ## `#[type_path = "my_crate::foo"]`
440///
441/// Optionally specifies a custom module path to use instead of [`module_path`].
442///
443/// This path does not include the final identifier.
444///
445/// ## `#[type_name = "RenamedType"]`
446///
447/// Optionally specifies a new terminating identifier for `TypePath`.
448///
449/// To use this attribute, `#[type_path = "..."]` must also be specified.
450#[proc_macro_derive(TypePath, attributes(type_path, type_name))]
451pub fn derive_type_path(input: TokenStream) -> TokenStream {
452    let ast = parse_macro_input!(input as DeriveInput);
453    let derive_data = match ReflectDerive::from_input(
454        &ast,
455        ReflectProvenance {
456            source: ReflectImplSource::DeriveLocalType,
457            trait_: ReflectTraitToImpl::TypePath,
458        },
459    ) {
460        Ok(data) => data,
461        Err(err) => return err.into_compile_error().into(),
462    };
463
464    let type_path_impl = impls::impl_type_path(derive_data.meta());
465
466    TokenStream::from(quote! {
467        const _: () = {
468            #type_path_impl
469        };
470    })
471}
472
473/// A macro that automatically generates type data for traits, which their implementors can then register.
474///
475/// The output of this macro is a struct that takes reflected instances of the implementor's type
476/// and returns the value as a trait object.
477/// Because of this, **it can only be used on [object-safe] traits.**
478///
479/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.
480/// The generated struct can be created using `FromType` with any type that implements the trait.
481/// The creation and registration of this generated struct as type data can be automatically handled
482/// by [`#[derive(Reflect)]`](Reflect).
483///
484/// # Example
485///
486/// ```ignore (bevy_reflect is not accessible from this crate)
487/// # use std::any::TypeId;
488/// # use bevy_reflect_derive::{Reflect, reflect_trait};
489/// #[reflect_trait] // Generates `ReflectMyTrait`
490/// trait MyTrait {
491///   fn print(&self) -> &str;
492/// }
493///
494/// #[derive(Reflect)]
495/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`
496/// struct SomeStruct;
497///
498/// impl MyTrait for SomeStruct {
499///   fn print(&self) -> &str {
500///     "Hello, World!"
501///   }
502/// }
503///
504/// // We can create the type data manually if we wanted:
505/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();
506///
507/// // Or we can simply get it from the registry:
508/// let mut registry = TypeRegistry::default();
509/// registry.register::<SomeStruct>();
510/// let my_trait = registry
511///   .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())
512///   .unwrap();
513///
514/// // Then use it on reflected data
515/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);
516/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();
517/// assert_eq!("Hello, World!", reflected_my_trait.print());
518/// ```
519///
520/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
521#[proc_macro_attribute]
522pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
523    trait_reflection::reflect_trait(&args, input)
524}
525
526/// Generates a wrapper type that can be used to "derive `Reflect`" for remote types.
527///
528/// This works by wrapping the remote type in a generated wrapper that has the `#[repr(transparent)]` attribute.
529/// This allows the two types to be safely [transmuted] back-and-forth.
530///
531/// # Defining the Wrapper
532///
533/// Before defining the wrapper type, please note that it is _required_ that all fields of the remote type are public.
534/// The generated code will, at times, need to access or mutate them,
535/// and we do not currently have a way to assign getters/setters to each field
536/// (but this may change in the future).
537///
538/// The wrapper definition should match the remote type 1-to-1.
539/// This includes the naming and ordering of the fields and variants.
540///
541/// Generics and lifetimes do _not_ need to have the same names, however, they _do_ need to follow the same order.
542/// Additionally, whether generics are inlined or placed in a where clause should not matter.
543///
544/// Lastly, all macros and doc-comments should be placed __below__ this attribute.
545/// If they are placed above, they will not be properly passed to the generated wrapper type.
546///
547/// # Example
548///
549/// Given a remote type, `RemoteType`:
550///
551/// ```
552/// #[derive(Default)]
553/// struct RemoteType<T>
554/// where
555///   T: Default + Clone,
556/// {
557///   pub foo: T,
558///   pub bar: usize
559/// }
560/// ```
561///
562/// We would define our wrapper type as such:
563///
564/// ```ignore
565/// use external_crate::RemoteType;
566///
567/// #[reflect_remote(RemoteType<T>)]
568/// #[derive(Default)]
569/// pub struct WrapperType<T: Default + Clone> {
570///   pub foo: T,
571///   pub bar: usize
572/// }
573/// ```
574///
575/// Apart from all the reflection trait implementations, this generates something like the following:
576///
577/// ```ignore
578/// use external_crate::RemoteType;
579///
580/// #[derive(Default)]
581/// #[repr(transparent)]
582/// pub struct Wrapper<T: Default + Clone>(RemoteType<T>);
583/// ```
584///
585/// # Usage as a Field
586///
587/// You can tell `Reflect` to use a remote type's wrapper internally on fields of a struct or enum.
588/// This allows the real type to be used as usual while `Reflect` handles everything internally.
589/// To do this, add the `#[reflect(remote = path::to::MyType)]` attribute to your field:
590///
591/// ```ignore
592/// #[derive(Reflect)]
593/// struct SomeStruct {
594///   #[reflect(remote = RemoteTypeWrapper)]
595///   data: RemoteType
596/// }
597/// ```
598///
599/// ## Safety
600///
601/// When using the `#[reflect(remote = path::to::MyType)]` field attribute, be sure you are defining the correct wrapper type.
602/// Internally, this field will be unsafely [transmuted], and is only sound if using a wrapper generated for the remote type.
603/// This also means keeping your wrapper definitions up-to-date with the remote types.
604///
605/// [transmuted]: std::mem::transmute
606#[proc_macro_attribute]
607pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {
608    remote::reflect_remote(args, input)
609}
610
611/// A macro used to generate reflection trait implementations for the given type.
612///
613/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.
614///
615/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits
616/// on primitives and other opaque types internally.
617///
618/// Since this macro also implements `TypePath`, the type path must be explicit.
619/// See [`impl_type_path!`] for the exact syntax.
620///
621/// # Examples
622///
623/// Types can be passed with or without registering type data:
624///
625/// ```ignore (bevy_reflect is not accessible from this crate)
626/// impl_reflect_opaque!(my_crate::Foo);
627/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));
628/// ```
629///
630/// Generic types can also specify their parameters and bounds:
631///
632/// ```ignore (bevy_reflect is not accessible from this crate)
633/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));
634/// ```
635///
636/// Custom type paths can be specified:
637///
638/// ```ignore (bevy_reflect is not accessible from this crate)
639/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));
640/// ```
641///
642/// [deriving `Reflect`]: Reflect
643#[proc_macro]
644pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {
645    let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);
646
647    let default_name = &def.type_path.segments.last().unwrap().ident;
648    let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
649        ReflectTypePath::Primitive(default_name)
650    } else {
651        ReflectTypePath::External {
652            path: &def.type_path,
653            custom_path: def.custom_path.map(|path| path.into_path(default_name)),
654            generics: &def.generics,
655        }
656    };
657
658    let meta = ReflectMeta::new(type_path, def.traits.unwrap_or_default());
659
660    #[cfg(feature = "documentation")]
661    let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));
662
663    let reflect_impls = impls::impl_opaque(&meta);
664    let from_reflect_impl = from_reflect::impl_opaque(&meta);
665
666    TokenStream::from(quote! {
667        const _: () = {
668            #reflect_impls
669            #from_reflect_impl
670        };
671    })
672}
673
674/// A replacement for `#[derive(Reflect)]` to be used with foreign types which
675/// the definitions of cannot be altered.
676///
677/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]
678/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,
679/// as this macro will do the job of both. This macro implements them using one of the reflect
680/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
681/// which have greater functionality. The type being reflected must be in scope, as you cannot
682/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.
683///
684/// It is necessary to add a `#[type_path = "my_crate::foo"]` attribute to all types.
685///
686/// It may be necessary to add `#[reflect(Default)]` for some types, specifically non-constructible
687/// foreign types. Without `Default` reflected for such types, you will usually get an arcane
688/// error message and fail to compile. If the type does not implement `Default`, it may not
689/// be possible to reflect without extending the macro.
690///
691///
692/// # Example
693/// Implementing `Reflect` for `bevy::prelude::Vec3` as a struct type:
694/// ```ignore (bevy_reflect is not accessible from this crate)
695/// use bevy::prelude::Vec3;
696///
697/// impl_reflect!(
698///     #[reflect(PartialEq, Serialize, Deserialize, Default)]
699///     #[type_path = "bevy::prelude"]
700///     struct Vec3 {
701///         x: f32,
702///         y: f32,
703///         z: f32
704///     }
705/// );
706/// ```
707#[proc_macro]
708pub fn impl_reflect(input: TokenStream) -> TokenStream {
709    let ast = parse_macro_input!(input as DeriveInput);
710    match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
711}
712
713/// A macro used to generate a `FromReflect` trait implementation for the given type.
714///
715/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using
716/// the `#[reflect(opaque)]` container attribute.
717///
718/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on
719/// primitives and other opaque types internally.
720///
721/// Please note that this macro will not work with any type that [derives `Reflect`] normally
722/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`
723/// by default.
724///
725/// # Examples
726///
727/// ```ignore (bevy_reflect is not accessible from this crate)
728/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);
729/// ```
730///
731/// [deriving `FromReflect`]: FromReflect
732/// [derives `Reflect`]: Reflect
733#[proc_macro]
734pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {
735    let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);
736
737    let default_name = &def.type_path.segments.last().unwrap().ident;
738    let type_path = if def.type_path.leading_colon.is_none()
739        && def.custom_path.is_none()
740        && def.generics.params.is_empty()
741    {
742        ReflectTypePath::Primitive(default_name)
743    } else {
744        ReflectTypePath::External {
745            path: &def.type_path,
746            custom_path: def.custom_path.map(|alias| alias.into_path(default_name)),
747            generics: &def.generics,
748        }
749    };
750
751    let from_reflect_impl =
752        from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));
753
754    TokenStream::from(quote! {
755        const _: () = {
756            #from_reflect_impl
757        };
758    })
759}
760
761/// A replacement for [deriving `TypePath`] for use on foreign types.
762///
763/// Since (unlike the derive) this macro may be invoked in a different module to where the type is defined,
764/// it requires an 'absolute' path definition.
765///
766/// Specifically, a leading `::` denoting a global path must be specified
767/// or a preceding `(in my_crate::foo)` to specify the custom path must be used.
768///
769/// # Examples
770///
771/// Implementing `TypePath` on a foreign type:
772/// ```ignore (bevy_reflect is not accessible from this crate)
773/// impl_type_path!(::foreign_crate::foo::bar::Baz);
774/// ```
775///
776/// On a generic type (this can also accept trait bounds):
777/// ```ignore (bevy_reflect is not accessible from this crate)
778/// impl_type_path!(::foreign_crate::Foo<T>);
779/// impl_type_path!(::foreign_crate::Goo<T: ?Sized>);
780/// ```
781///
782/// On a primitive (note this will not compile for a non-primitive type):
783/// ```ignore (bevy_reflect is not accessible from this crate)
784/// impl_type_path!(bool);
785/// ```
786///
787/// With a custom type path:
788/// ```ignore (bevy_reflect is not accessible from this crate)
789/// impl_type_path!((in other_crate::foo::bar) Baz);
790/// ```
791///
792/// With a custom type path and a custom type name:
793/// ```ignore (bevy_reflect is not accessible from this crate)
794/// impl_type_path!((in other_crate::foo as Baz) Bar);
795/// ```
796///
797/// [deriving `TypePath`]: TypePath
798#[proc_macro]
799pub fn impl_type_path(input: TokenStream) -> TokenStream {
800    let def = parse_macro_input!(input as NamedTypePathDef);
801
802    let type_path = match def {
803        NamedTypePathDef::External {
804            ref path,
805            custom_path,
806            ref generics,
807        } => {
808            let default_name = &path.segments.last().unwrap().ident;
809
810            ReflectTypePath::External {
811                path,
812                custom_path: custom_path.map(|path| path.into_path(default_name)),
813                generics,
814            }
815        }
816        NamedTypePathDef::Primitive(ref ident) => ReflectTypePath::Primitive(ident),
817    };
818
819    let meta = ReflectMeta::new(type_path, ContainerAttributes::default());
820
821    let type_path_impl = impls::impl_type_path(&meta);
822
823    TokenStream::from(quote! {
824        const _: () = {
825            #type_path_impl
826        };
827    })
828}