Skip to main content

bevy_reflect/
fields.rs

1use crate::{
2    attributes::{impl_custom_attribute_methods, CustomAttributes},
3    ty::impl_type_methods,
4    MaybeTyped, PartialReflect, Type, TypeInfo, TypePath,
5};
6use alloc::borrow::Cow;
7use core::fmt::{Display, Formatter};
8
9/// The named field of a reflected struct.
10#[derive(Clone, Debug)]
11pub struct NamedField {
12    name: &'static str,
13    type_info: fn() -> Option<&'static TypeInfo>,
14    ty: Type,
15    custom_attributes: CustomAttributes,
16    #[cfg(feature = "reflect_documentation")]
17    docs: Option<&'static str>,
18}
19
20impl NamedField {
21    /// Create a new [`NamedField`].
22    pub fn new<T: PartialReflect + MaybeTyped + TypePath>(name: &'static str) -> Self {
23        Self {
24            name,
25            type_info: T::maybe_type_info,
26            ty: Type::of::<T>(),
27            custom_attributes: CustomAttributes::default(),
28            #[cfg(feature = "reflect_documentation")]
29            docs: None,
30        }
31    }
32
33    /// Sets the docstring for this field.
34    #[cfg(feature = "reflect_documentation")]
35    pub fn with_docs(self, docs: Option<&'static str>) -> Self {
36        Self { docs, ..self }
37    }
38
39    /// Sets the custom attributes for this field.
40    pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
41        Self {
42            custom_attributes,
43            ..self
44        }
45    }
46
47    /// The name of the field.
48    pub fn name(&self) -> &'static str {
49        self.name
50    }
51
52    /// The [`TypeInfo`] of the field.
53    ///
54    ///
55    /// Returns `None` if the field does not contain static type information,
56    /// such as for dynamic types.
57    pub fn type_info(&self) -> Option<&'static TypeInfo> {
58        (self.type_info)()
59    }
60
61    impl_type_methods!(ty);
62
63    /// The docstring of this field, if any.
64    #[cfg(feature = "reflect_documentation")]
65    pub fn docs(&self) -> Option<&'static str> {
66        self.docs
67    }
68
69    impl_custom_attribute_methods!(self.custom_attributes, "field");
70}
71
72/// The unnamed field of a reflected tuple or tuple struct.
73#[derive(Clone, Debug)]
74pub struct UnnamedField {
75    index: usize,
76    type_info: fn() -> Option<&'static TypeInfo>,
77    ty: Type,
78    custom_attributes: CustomAttributes,
79    #[cfg(feature = "reflect_documentation")]
80    docs: Option<&'static str>,
81}
82
83impl UnnamedField {
84    /// Create a new [`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: CustomAttributes::default(),
91            #[cfg(feature = "reflect_documentation")]
92            docs: None,
93        }
94    }
95
96    /// Sets the docstring for this field.
97    #[cfg(feature = "reflect_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,
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 = "reflect_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    /// Access a field by name.
139    Named(Cow<'static, str>),
140    /// Access a field by index.
141    Unnamed(usize),
142}
143
144impl Display for FieldId {
145    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
146        match self {
147            Self::Named(name) => Display::fmt(name, f),
148            Self::Unnamed(index) => Display::fmt(index, f),
149        }
150    }
151}