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