1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::string::String;
4use core::any::Any;
5use core::fmt;
6
7use crate::iter::PairIterMut;
8use crate::iter::ValueIterMut;
9use crate::struct_::StructValue;
10use crate::tuple::TupleValue;
11use crate::type_info::graph::NodeId;
12use crate::type_info::graph::OpaqueNode;
13use crate::type_info::graph::TypeGraph;
14use crate::DescribeType;
15use crate::FromReflect;
16use crate::Reflect;
17use crate::ReflectMut;
18use crate::ReflectOwned;
19use crate::ReflectRef;
20use crate::Struct;
21use crate::Tuple;
22use crate::Value;
23
24pub trait Enum: Reflect {
28 fn variant_name(&self) -> &str;
29
30 fn variant_kind(&self) -> VariantKind;
31
32 fn field(&self, name: &str) -> Option<&dyn Reflect>;
33
34 fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
35
36 fn field_at(&self, index: usize) -> Option<&dyn Reflect>;
37
38 fn name_at(&self, index: usize) -> Option<&str>;
39
40 fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
41
42 fn fields(&self) -> VariantFieldIter<'_>;
43
44 fn fields_mut(&mut self) -> VariantFieldIterMut<'_>;
45
46 fn variants_len(&self) -> usize;
47
48 fn fields_len(&self) -> usize;
49}
50
51impl fmt::Debug for dyn Enum {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 self.as_reflect().debug(f)
54 }
55}
56
57#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
58pub enum VariantKind {
59 Struct,
60 Tuple,
61 Unit,
62}
63
64#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
65#[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))]
66#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67pub struct EnumValue {
68 name: String,
69 kind: EnumValueKind,
70}
71
72#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
73#[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))]
74#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75enum EnumValueKind {
76 Struct(StructValue),
77 Tuple(TupleValue),
78 Unit,
79}
80
81impl EnumValue {
82 pub fn new_struct_variant(name: impl Into<String>) -> StructVariantBuilder {
83 Self::new_struct_variant_with_capacity(name, 0)
84 }
85
86 pub fn new_struct_variant_with_capacity(
87 name: impl Into<String>,
88 capacity: usize,
89 ) -> StructVariantBuilder {
90 StructVariantBuilder {
91 inner: Self {
92 name: name.into(),
93 kind: EnumValueKind::Struct(StructValue::with_capacity(capacity)),
94 },
95 }
96 }
97
98 pub fn new_tuple_variant(name: impl Into<String>) -> TupleVariantBuilder {
99 Self::new_tuple_variant_with_capacity(name, 0)
100 }
101
102 pub fn new_tuple_variant_with_capacity(
103 name: impl Into<String>,
104 capacity: usize,
105 ) -> TupleVariantBuilder {
106 TupleVariantBuilder {
107 inner: Self {
108 name: name.into(),
109 kind: EnumValueKind::Tuple(TupleValue::with_capacity(capacity)),
110 },
111 }
112 }
113
114 pub fn new_unit_variant(name: impl Into<String>) -> Self {
115 Self {
116 name: name.into(),
117 kind: EnumValueKind::Unit,
118 }
119 }
120
121 #[track_caller]
122 pub fn with_struct_field(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
123 self.set_struct_field(name, value);
124 self
125 }
126
127 #[track_caller]
128 pub fn with_tuple_field(mut self, value: impl Into<Value>) -> Self {
129 self.push_tuple_field(value);
130 self
131 }
132
133 #[track_caller]
134 pub fn set_struct_field(&mut self, name: impl Into<String>, value: impl Into<Value>) {
135 match &mut self.kind {
136 EnumValueKind::Struct(struct_) => {
137 struct_.set_field(name, value);
138 }
139 EnumValueKind::Tuple(_) => panic!("Cannot set fields on tuple variants"),
140 EnumValueKind::Unit => panic!("Cannot set fields on unit variants"),
141 }
142 }
143
144 #[track_caller]
145 pub fn push_tuple_field(&mut self, value: impl Into<Value>) {
146 match &mut self.kind {
147 EnumValueKind::Struct(_) => {
148 panic!("Cannot push fields on struct variants")
149 }
150 EnumValueKind::Tuple(tuple) => {
151 tuple.push_field(value);
152 }
153 EnumValueKind::Unit => panic!("Cannot set fields on unit variants"),
154 }
155 }
156}
157
158#[derive(Debug, Clone)]
159pub struct StructVariantBuilder {
160 inner: EnumValue,
161}
162
163impl StructVariantBuilder {
164 pub fn with_struct_field(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
165 self.set_struct_field(name, value);
166 self
167 }
168
169 pub fn set_struct_field(&mut self, name: impl Into<String>, value: impl Into<Value>) {
170 self.inner.set_struct_field(name, value);
171 }
172
173 pub fn finish(self) -> EnumValue {
174 self.inner
175 }
176}
177
178#[derive(Debug, Clone)]
179pub struct TupleVariantBuilder {
180 inner: EnumValue,
181}
182
183impl TupleVariantBuilder {
184 pub fn with_tuple_field(mut self, value: impl Into<Value>) -> Self {
185 self.push_tuple_field(value);
186 self
187 }
188
189 pub fn push_tuple_field(&mut self, value: impl Into<Value>) {
190 self.inner.push_tuple_field(value);
191 }
192
193 pub fn finish(self) -> EnumValue {
194 self.inner
195 }
196}
197
198impl DescribeType for EnumValue {
199 fn build(graph: &mut TypeGraph) -> NodeId {
200 graph.get_or_build_node_with::<Self, _>(|graph| {
201 OpaqueNode::new::<Self>(Default::default(), graph)
202 })
203 }
204}
205
206impl Reflect for EnumValue {
207 trivial_reflect_methods!();
208
209 fn patch(&mut self, value: &dyn Reflect) {
210 if let Some(enum_) = value.reflect_ref().as_enum() {
211 if self.variant_name() == enum_.variant_name() {
212 for (idx, field) in self.fields_mut().enumerate() {
213 match field {
214 VariantFieldMut::Struct(name, value) => {
215 if let Some(new_value) = enum_.field(name) {
216 value.patch(new_value);
217 }
218 }
219 VariantFieldMut::Tuple(value) => {
220 if let Some(new_value) = enum_.field_at(idx) {
221 value.patch(new_value);
222 }
223 }
224 }
225 }
226 } else if let Some(new) = Self::from_reflect(value) {
227 *self = new;
228 }
229 }
230 }
231
232 fn to_value(&self) -> Value {
233 self.clone().into()
234 }
235
236 fn clone_reflect(&self) -> Box<dyn Reflect> {
237 Box::new(self.clone())
238 }
239
240 fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 if f.alternate() {
242 write!(f, "{self:#?}")
243 } else {
244 write!(f, "{self:?}")
245 }
246 }
247
248 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
249 ReflectOwned::Enum(self)
250 }
251
252 fn reflect_ref(&self) -> ReflectRef<'_> {
253 ReflectRef::Enum(self)
254 }
255
256 fn reflect_mut(&mut self) -> ReflectMut<'_> {
257 ReflectMut::Enum(self)
258 }
259}
260
261impl Enum for EnumValue {
262 fn variant_name(&self) -> &str {
263 &self.name
264 }
265
266 fn variant_kind(&self) -> VariantKind {
267 match &self.kind {
268 EnumValueKind::Struct(_) => VariantKind::Struct,
269 EnumValueKind::Tuple(_) => VariantKind::Tuple,
270 EnumValueKind::Unit => VariantKind::Unit,
271 }
272 }
273
274 fn field(&self, name: &str) -> Option<&dyn Reflect> {
275 match &self.kind {
276 EnumValueKind::Struct(struct_) => struct_.field(name),
277 EnumValueKind::Tuple(_) => None,
278 EnumValueKind::Unit => None,
279 }
280 }
281
282 fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect> {
283 match &mut self.kind {
284 EnumValueKind::Struct(struct_) => struct_.field_mut(name),
285 EnumValueKind::Tuple(_) => None,
286 EnumValueKind::Unit => None,
287 }
288 }
289
290 fn field_at(&self, index: usize) -> Option<&dyn Reflect> {
291 match &self.kind {
292 EnumValueKind::Struct(struct_) => struct_.field_at(index),
293 EnumValueKind::Tuple(tuple) => tuple.field_at(index),
294 EnumValueKind::Unit => None,
295 }
296 }
297
298 fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
299 match &mut self.kind {
300 EnumValueKind::Struct(struct_) => struct_.field_at_mut(index),
301 EnumValueKind::Tuple(tuple) => tuple.field_at_mut(index),
302 EnumValueKind::Unit => None,
303 }
304 }
305
306 fn fields(&self) -> VariantFieldIter<'_> {
307 VariantFieldIter::new(self)
308 }
309
310 fn fields_mut(&mut self) -> VariantFieldIterMut<'_> {
311 match &mut self.kind {
312 EnumValueKind::Struct(inner) => {
313 VariantFieldIterMut(VariantFieldIterInnerMut::Struct(inner.fields_mut()))
314 }
315 EnumValueKind::Tuple(inner) => {
316 VariantFieldIterMut(VariantFieldIterInnerMut::Tuple(inner.fields_mut()))
317 }
318 EnumValueKind::Unit => VariantFieldIterMut::empty(),
319 }
320 }
321
322 fn variants_len(&self) -> usize {
323 1
324 }
325
326 fn fields_len(&self) -> usize {
327 match &self.kind {
328 EnumValueKind::Struct(inner) => inner.fields_len(),
329 EnumValueKind::Tuple(inner) => inner.fields_len(),
330 EnumValueKind::Unit => 0,
331 }
332 }
333
334 fn name_at(&self, index: usize) -> Option<&str> {
335 match &self.kind {
336 EnumValueKind::Struct(inner) => inner.name_at(index),
337 EnumValueKind::Tuple(_) => None,
338 EnumValueKind::Unit => None,
339 }
340 }
341}
342
343impl FromReflect for EnumValue {
344 #[track_caller]
345 fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
346 let enum_ = reflect.reflect_ref().as_enum()?;
347
348 let kind = match enum_.variant_kind() {
349 VariantKind::Struct => {
350 let struct_ = enum_
351 .fields()
352 .fold(StructValue::default(), |builder, field| match field {
353 VariantField::Struct(name, value) => {
354 builder.with_field(name, value.to_value())
355 }
356 VariantField::Tuple(_) => {
357 panic!("iterator over fields in struct variant yielded a tuple field")
358 }
359 });
360 EnumValueKind::Struct(struct_)
361 }
362 VariantKind::Tuple => {
363 let tuple =
364 enum_
365 .fields()
366 .fold(TupleValue::default(), |builder, field| match field {
367 VariantField::Struct(_, _) => {
368 panic!(
369 "iterator over fields in tuple variant yielded a struct field"
370 )
371 }
372 VariantField::Tuple(value) => builder.with_field(value.to_value()),
373 });
374 EnumValueKind::Tuple(tuple)
375 }
376 VariantKind::Unit => EnumValueKind::Unit,
377 };
378
379 Some(EnumValue {
380 name: enum_.variant_name().to_owned(),
381 kind,
382 })
383 }
384}
385
386#[derive(Debug)]
387pub struct VariantFieldIter<'a> {
388 enum_: &'a dyn Enum,
389 index: usize,
390}
391
392impl<'a> VariantFieldIter<'a> {
393 pub fn new(enum_: &'a dyn Enum) -> Self {
394 Self { enum_, index: 0 }
395 }
396}
397
398impl<'a> Iterator for VariantFieldIter<'a> {
399 type Item = VariantField<'a>;
400
401 fn next(&mut self) -> Option<Self::Item> {
402 let item = match self.enum_.variant_kind() {
403 VariantKind::Struct => {
404 let name = self.enum_.name_at(self.index)?;
405 let value = self.enum_.field_at(self.index)?;
406 VariantField::Struct(name, value)
407 }
408 VariantKind::Tuple => {
409 let value = self.enum_.field_at(self.index)?;
410 VariantField::Tuple(value)
411 }
412 VariantKind::Unit => return None,
413 };
414 self.index += 1;
415 Some(item)
416 }
417}
418
419#[derive(Debug)]
420pub enum VariantField<'a> {
421 Struct(&'a str, &'a dyn Reflect),
422 Tuple(&'a dyn Reflect),
423}
424
425#[derive(Debug)]
426pub struct VariantFieldIterMut<'a>(VariantFieldIterInnerMut<'a>);
427
428impl<'a> VariantFieldIterMut<'a> {
429 pub fn new_struct_variant<I>(iter: I) -> Self
430 where
431 I: IntoIterator<Item = (&'a str, &'a mut dyn Reflect)> + 'a,
432 {
433 Self(VariantFieldIterInnerMut::Struct(Box::new(iter.into_iter())))
434 }
435
436 pub fn new_tuple_variant<I>(iter: I) -> Self
437 where
438 I: IntoIterator<Item = &'a mut dyn Reflect> + 'a,
439 {
440 Self(VariantFieldIterInnerMut::Tuple(Box::new(iter.into_iter())))
441 }
442
443 pub fn empty() -> Self {
444 Self(VariantFieldIterInnerMut::Empty)
445 }
446}
447
448enum VariantFieldIterInnerMut<'a> {
449 Struct(PairIterMut<'a>),
450 Tuple(ValueIterMut<'a>),
451 Empty,
452}
453
454impl core::fmt::Debug for VariantFieldIterInnerMut<'_> {
455 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456 match self {
457 Self::Struct(_) => f.debug_tuple("Struct").finish(),
458 Self::Tuple(_) => f.debug_tuple("Tuple").finish(),
459 Self::Empty => write!(f, "Empty"),
460 }
461 }
462}
463
464#[derive(Debug)]
465pub enum VariantFieldMut<'a> {
466 Struct(&'a str, &'a mut dyn Reflect),
467 Tuple(&'a mut dyn Reflect),
468}
469
470impl<'a> Iterator for VariantFieldIterMut<'a> {
471 type Item = VariantFieldMut<'a>;
472
473 fn next(&mut self) -> Option<Self::Item> {
474 match &mut self.0 {
475 VariantFieldIterInnerMut::Struct(iter) => iter
476 .next()
477 .map(|(name, value)| VariantFieldMut::Struct(name, value)),
478 VariantFieldIterInnerMut::Tuple(iter) => iter.next().map(VariantFieldMut::Tuple),
479 VariantFieldIterInnerMut::Empty => None,
480 }
481 }
482}