mirror_mirror/
enum_.rs

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
24/// A reflected enum type.
25///
26/// Will be implemented by `#[derive(Reflect)]` on enums.
27pub 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}