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