bevy_reflect/
fields.rs

1use crate::{
2    attributes::{impl_custom_attribute_methods, CustomAttributes},
3    type_info::impl_type_methods,
4    MaybeTyped, PartialReflect, Type, TypeInfo, TypePath,
5};
6use alloc::borrow::Cow;
7use bevy_platform::sync::Arc;
8use core::fmt::{Display, Formatter};
9
10/// The named field of a reflected struct.
11#[derive(Clone, Debug)]
12pub struct NamedField {
13    name: &'static str,
14    type_info: fn() -> Option<&'static TypeInfo>,
15    ty: Type,
16    custom_attributes: Arc<CustomAttributes>,
17    #[cfg(feature = "documentation")]
18    docs: Option<&'static str>,
19}
20
21impl NamedField {
22    /// Create a new [`NamedField`].
23    pub fn new<T: PartialReflect + MaybeTyped + TypePath>(name: &'static str) -> Self {
24        Self {
25            name,
26            type_info: T::maybe_type_info,
27            ty: Type::of::<T>(),
28            custom_attributes: Arc::new(CustomAttributes::default()),
29            #[cfg(feature = "documentation")]
30            docs: None,
31        }
32    }
33
34    /// Sets the docstring for this field.
35    #[cfg(feature = "documentation")]
36    pub fn with_docs(self, docs: Option<&'static str>) -> Self {
37        Self { docs, ..self }
38    }
39
40    /// Sets the custom attributes for this field.
41    pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
42        Self {
43            custom_attributes: Arc::new(custom_attributes),
44            ..self
45        }
46    }
47
48    /// The name of the field.
49    pub fn name(&self) -> &'static str {
50        self.name
51    }
52
53    /// The [`TypeInfo`] of the field.
54    ///
55    ///
56    /// Returns `None` if the field does not contain static type information,
57    /// such as for dynamic types.
58    pub fn type_info(&self) -> Option<&'static TypeInfo> {
59        (self.type_info)()
60    }
61
62    impl_type_methods!(ty);
63
64    /// The docstring of this field, if any.
65    #[cfg(feature = "documentation")]
66    pub fn docs(&self) -> Option<&'static str> {
67        self.docs
68    }
69
70    impl_custom_attribute_methods!(self.custom_attributes, "field");
71}
72
73/// The unnamed field of a reflected tuple or tuple struct.
74#[derive(Clone, Debug)]
75pub struct UnnamedField {
76    index: usize,
77    type_info: fn() -> Option<&'static TypeInfo>,
78    ty: Type,
79    custom_attributes: Arc<CustomAttributes>,
80    #[cfg(feature = "documentation")]
81    docs: Option<&'static str>,
82}
83
84impl UnnamedField {
85    /// Create a new [`UnnamedField`].
86    pub fn new<T: PartialReflect + MaybeTyped + TypePath>(index: usize) -> Self {
87        Self {
88            index,
89            type_info: T::maybe_type_info,
90            ty: Type::of::<T>(),
91            custom_attributes: Arc::new(CustomAttributes::default()),
92            #[cfg(feature = "documentation")]
93            docs: None,
94        }
95    }
96
97    /// Sets the docstring for this field.
98    #[cfg(feature = "documentation")]
99    pub fn with_docs(self, docs: Option<&'static str>) -> Self {
100        Self { docs, ..self }
101    }
102
103    /// Sets the custom attributes for this field.
104    pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
105        Self {
106            custom_attributes: Arc::new(custom_attributes),
107            ..self
108        }
109    }
110
111    /// Returns the index of the field.
112    pub fn index(&self) -> usize {
113        self.index
114    }
115
116    /// The [`TypeInfo`] of the field.
117    ///
118    ///
119    /// Returns `None` if the field does not contain static type information,
120    /// such as for dynamic types.
121    pub fn type_info(&self) -> Option<&'static TypeInfo> {
122        (self.type_info)()
123    }
124
125    impl_type_methods!(ty);
126
127    /// The docstring of this field, if any.
128    #[cfg(feature = "documentation")]
129    pub fn docs(&self) -> Option<&'static str> {
130        self.docs
131    }
132
133    impl_custom_attribute_methods!(self.custom_attributes, "field");
134}
135
136/// A representation of a field's accessor.
137#[derive(Clone, Debug, PartialEq, Eq)]
138pub enum FieldId {
139    /// Access a field by name.
140    Named(Cow<'static, str>),
141    /// Access a field by index.
142    Unnamed(usize),
143}
144
145impl Display for FieldId {
146    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
147        match self {
148            Self::Named(name) => Display::fmt(name, f),
149            Self::Unnamed(index) => Display::fmt(index, f),
150        }
151    }
152}