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    pub fn new<T: PartialReflect + MaybeTyped + TypePath>(index: usize) -> Self {
86        Self {
87            index,
88            type_info: T::maybe_type_info,
89            ty: Type::of::<T>(),
90            custom_attributes: Arc::new(CustomAttributes::default()),
91            #[cfg(feature = "documentation")]
92            docs: None,
93        }
94    }
95
96    /// Sets the docstring for this field.
97    #[cfg(feature = "documentation")]
98    pub fn with_docs(self, docs: Option<&'static str>) -> Self {
99        Self { docs, ..self }
100    }
101
102    /// Sets the custom attributes for this field.
103    pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
104        Self {
105            custom_attributes: Arc::new(custom_attributes),
106            ..self
107        }
108    }
109
110    /// Returns the index of the field.
111    pub fn index(&self) -> usize {
112        self.index
113    }
114
115    /// The [`TypeInfo`] of the field.
116    ///
117    ///
118    /// Returns `None` if the field does not contain static type information,
119    /// such as for dynamic types.
120    pub fn type_info(&self) -> Option<&'static TypeInfo> {
121        (self.type_info)()
122    }
123
124    impl_type_methods!(ty);
125
126    /// The docstring of this field, if any.
127    #[cfg(feature = "documentation")]
128    pub fn docs(&self) -> Option<&'static str> {
129        self.docs
130    }
131
132    impl_custom_attribute_methods!(self.custom_attributes, "field");
133}
134
135/// A representation of a field's accessor.
136#[derive(Clone, Debug, PartialEq, Eq)]
137pub enum FieldId {
138    Named(Cow<'static, str>),
139    Unnamed(usize),
140}
141
142impl Display for FieldId {
143    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
144        match self {
145            Self::Named(name) => Display::fmt(name, f),
146            Self::Unnamed(index) => Display::fmt(index, f),
147        }
148    }
149}