facet_reflect/wip/
enum_.rs1use facet_core::{Def, FieldError, Variant};
2#[cfg(feature = "log")]
3use owo_colors::OwoColorize;
4
5use crate::trace;
6use crate::{ISet, ReflectError, Wip};
7
8impl Wip<'_> {
9 pub fn variant(mut self, index: usize) -> Result<Self, ReflectError> {
20 let frame = self.frames.last_mut().unwrap();
21 let shape = frame.shape;
22 let Def::Enum(def) = shape.def else {
23 return Err(ReflectError::WasNotA {
24 expected: "enum",
25 actual: shape,
26 });
27 };
28
29 if index >= def.variants.len() {
30 return Err(ReflectError::FieldError {
31 shape,
32 field_error: FieldError::IndexOutOfBounds,
33 });
34 }
35
36 let variant = def.variants[index];
37
38 ISet::clear(&mut frame.istate.fields);
40
41 let discriminant = variant.discriminant;
43 unsafe {
44 let data_ptr = frame.data.as_mut_byte_ptr();
45 match def.repr {
46 facet_core::EnumRepr::U8 => *data_ptr = discriminant as u8,
47 facet_core::EnumRepr::U16 => *(data_ptr as *mut u16) = discriminant as u16,
48 facet_core::EnumRepr::U32 => *(data_ptr as *mut u32) = discriminant as u32,
49 facet_core::EnumRepr::U64 => *(data_ptr as *mut u64) = discriminant as u64,
50 facet_core::EnumRepr::USize => *(data_ptr as *mut usize) = discriminant as usize,
51 facet_core::EnumRepr::I8 => *(data_ptr as *mut i8) = discriminant as i8,
52 facet_core::EnumRepr::I16 => *(data_ptr as *mut i16) = discriminant as i16,
53 facet_core::EnumRepr::I32 => *(data_ptr as *mut i32) = discriminant as i32,
54 facet_core::EnumRepr::I64 => *(data_ptr as *mut i64) = discriminant,
55 facet_core::EnumRepr::ISize => *(data_ptr as *mut isize) = discriminant as isize,
56 _ => {
57 *(data_ptr as *mut u32) = discriminant as u32;
59 }
60 }
61 }
62
63 frame.istate.variant = Some(variant);
65
66 trace!(
67 "[{}] Selecting variant {} of {} with discriminant {}",
68 self.frames.len(),
69 variant.name.blue(),
70 shape.blue(),
71 discriminant
72 );
73
74 Ok(self)
75 }
76
77 pub fn variant_named(self, name: &str) -> Result<Self, ReflectError> {
88 let frame = self.frames.last().unwrap();
89 let shape = frame.shape;
90 let Def::Enum(def) = shape.def else {
91 return Err(ReflectError::WasNotA {
92 expected: "enum",
93 actual: shape,
94 });
95 };
96
97 let index =
98 def.variants
99 .iter()
100 .position(|v| v.name == name)
101 .ok_or(ReflectError::FieldError {
102 shape,
103 field_error: FieldError::NoSuchField,
104 })?;
105
106 self.variant(index)
107 }
108
109 pub fn find_variant(&self, name: &str) -> Option<(usize, Variant)> {
120 let frame = self.frames.last()?;
121 if let Def::Enum(def) = frame.shape.def {
122 def.variants
123 .iter()
124 .enumerate()
125 .find(|(_, v)| v.name == name)
126 .map(|(i, &v)| (i, v))
127 } else {
128 None
129 }
130 }
131
132 pub fn selected_variant(&self) -> Option<Variant> {
139 let frame = self.frames.last()?;
140 frame.istate.variant
141 }
142}