bevy_reflect/enums/
variants.rs1use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
2use crate::{NamedField, UnnamedField};
3use bevy_utils::HashMap;
4use std::slice::Iter;
5use std::sync::Arc;
6
7#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
9pub enum VariantType {
10 Struct,
20 Tuple,
28 Unit,
36}
37
38#[derive(Clone, Debug)]
40pub enum VariantInfo {
41 Struct(StructVariantInfo),
51 Tuple(TupleVariantInfo),
59 Unit(UnitVariantInfo),
67}
68
69impl VariantInfo {
70 pub fn name(&self) -> &'static str {
71 match self {
72 Self::Struct(info) => info.name(),
73 Self::Tuple(info) => info.name(),
74 Self::Unit(info) => info.name(),
75 }
76 }
77
78 #[cfg(feature = "documentation")]
80 pub fn docs(&self) -> Option<&str> {
81 match self {
82 Self::Struct(info) => info.docs(),
83 Self::Tuple(info) => info.docs(),
84 Self::Unit(info) => info.docs(),
85 }
86 }
87
88 impl_custom_attribute_methods!(
89 self,
90 match self {
91 Self::Struct(info) => info.custom_attributes(),
92 Self::Tuple(info) => info.custom_attributes(),
93 Self::Unit(info) => info.custom_attributes(),
94 },
95 "variant"
96 );
97}
98
99#[derive(Clone, Debug)]
101pub struct StructVariantInfo {
102 name: &'static str,
103 fields: Box<[NamedField]>,
104 field_names: Box<[&'static str]>,
105 field_indices: HashMap<&'static str, usize>,
106 custom_attributes: Arc<CustomAttributes>,
107 #[cfg(feature = "documentation")]
108 docs: Option<&'static str>,
109}
110
111impl StructVariantInfo {
112 pub fn new(name: &'static str, fields: &[NamedField]) -> Self {
114 let field_indices = Self::collect_field_indices(fields);
115 let field_names = fields.iter().map(|field| field.name()).collect();
116 Self {
117 name,
118 fields: fields.to_vec().into_boxed_slice(),
119 field_names,
120 field_indices,
121 custom_attributes: Arc::new(CustomAttributes::default()),
122 #[cfg(feature = "documentation")]
123 docs: None,
124 }
125 }
126
127 #[cfg(feature = "documentation")]
129 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
130 Self { docs, ..self }
131 }
132
133 pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
135 Self {
136 custom_attributes: Arc::new(custom_attributes),
137 ..self
138 }
139 }
140
141 pub fn name(&self) -> &'static str {
143 self.name
144 }
145
146 pub fn field_names(&self) -> &[&'static str] {
148 &self.field_names
149 }
150
151 pub fn field(&self, name: &str) -> Option<&NamedField> {
153 self.field_indices
154 .get(name)
155 .map(|index| &self.fields[*index])
156 }
157
158 pub fn field_at(&self, index: usize) -> Option<&NamedField> {
160 self.fields.get(index)
161 }
162
163 pub fn index_of(&self, name: &str) -> Option<usize> {
165 self.field_indices.get(name).copied()
166 }
167
168 pub fn iter(&self) -> Iter<'_, NamedField> {
170 self.fields.iter()
171 }
172
173 pub fn field_len(&self) -> usize {
175 self.fields.len()
176 }
177
178 fn collect_field_indices(fields: &[NamedField]) -> HashMap<&'static str, usize> {
179 fields
180 .iter()
181 .enumerate()
182 .map(|(index, field)| (field.name(), index))
183 .collect()
184 }
185
186 #[cfg(feature = "documentation")]
188 pub fn docs(&self) -> Option<&'static str> {
189 self.docs
190 }
191
192 impl_custom_attribute_methods!(self.custom_attributes, "variant");
193}
194
195#[derive(Clone, Debug)]
197pub struct TupleVariantInfo {
198 name: &'static str,
199 fields: Box<[UnnamedField]>,
200 custom_attributes: Arc<CustomAttributes>,
201 #[cfg(feature = "documentation")]
202 docs: Option<&'static str>,
203}
204
205impl TupleVariantInfo {
206 pub fn new(name: &'static str, fields: &[UnnamedField]) -> Self {
208 Self {
209 name,
210 fields: fields.to_vec().into_boxed_slice(),
211 custom_attributes: Arc::new(CustomAttributes::default()),
212 #[cfg(feature = "documentation")]
213 docs: None,
214 }
215 }
216
217 #[cfg(feature = "documentation")]
219 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
220 Self { docs, ..self }
221 }
222
223 pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
225 Self {
226 custom_attributes: Arc::new(custom_attributes),
227 ..self
228 }
229 }
230
231 pub fn name(&self) -> &'static str {
233 self.name
234 }
235
236 pub fn field_at(&self, index: usize) -> Option<&UnnamedField> {
238 self.fields.get(index)
239 }
240
241 pub fn iter(&self) -> Iter<'_, UnnamedField> {
243 self.fields.iter()
244 }
245
246 pub fn field_len(&self) -> usize {
248 self.fields.len()
249 }
250
251 #[cfg(feature = "documentation")]
253 pub fn docs(&self) -> Option<&'static str> {
254 self.docs
255 }
256
257 impl_custom_attribute_methods!(self.custom_attributes, "variant");
258}
259
260#[derive(Clone, Debug)]
262pub struct UnitVariantInfo {
263 name: &'static str,
264 custom_attributes: Arc<CustomAttributes>,
265 #[cfg(feature = "documentation")]
266 docs: Option<&'static str>,
267}
268
269impl UnitVariantInfo {
270 pub fn new(name: &'static str) -> Self {
272 Self {
273 name,
274 custom_attributes: Arc::new(CustomAttributes::default()),
275 #[cfg(feature = "documentation")]
276 docs: None,
277 }
278 }
279
280 #[cfg(feature = "documentation")]
282 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
283 Self { docs, ..self }
284 }
285
286 pub fn with_custom_attributes(self, custom_attributes: CustomAttributes) -> Self {
288 Self {
289 custom_attributes: Arc::new(custom_attributes),
290 ..self
291 }
292 }
293
294 pub fn name(&self) -> &'static str {
296 self.name
297 }
298
299 #[cfg(feature = "documentation")]
301 pub fn docs(&self) -> Option<&'static str> {
302 self.docs
303 }
304
305 impl_custom_attribute_methods!(self.custom_attributes, "variant");
306}