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