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 index,
34 bound: def.variants.len(),
35 },
36 });
37 }
38
39 let variant = def.variants[index];
40
41 ISet::clear(&mut frame.istate.fields);
43
44 let discriminant = variant.discriminant;
46 unsafe {
47 let data_ptr = frame.data.as_mut_byte_ptr();
48 match def.repr {
49 facet_core::EnumRepr::U8 => *data_ptr = discriminant as u8,
50 facet_core::EnumRepr::U16 => *(data_ptr as *mut u16) = discriminant as u16,
51 facet_core::EnumRepr::U32 => *(data_ptr as *mut u32) = discriminant as u32,
52 facet_core::EnumRepr::U64 => *(data_ptr as *mut u64) = discriminant as u64,
53 facet_core::EnumRepr::USize => *(data_ptr as *mut usize) = discriminant as usize,
54 facet_core::EnumRepr::I8 => *(data_ptr as *mut i8) = discriminant as i8,
55 facet_core::EnumRepr::I16 => *(data_ptr as *mut i16) = discriminant as i16,
56 facet_core::EnumRepr::I32 => *(data_ptr as *mut i32) = discriminant as i32,
57 facet_core::EnumRepr::I64 => *(data_ptr as *mut i64) = discriminant,
58 facet_core::EnumRepr::ISize => *(data_ptr as *mut isize) = discriminant as isize,
59 _ => {
60 *(data_ptr as *mut u32) = discriminant as u32;
62 }
63 }
64 }
65
66 frame.istate.variant = Some(variant);
68
69 trace!(
70 "[{}] Selecting variant {} of {} with discriminant {}",
71 self.frames.len(),
72 variant.name.blue(),
73 shape.blue(),
74 discriminant
75 );
76
77 Ok(self)
78 }
79
80 pub fn variant_named(self, name: &str) -> Result<Self, ReflectError> {
91 let frame = self.frames.last().unwrap();
92 let shape = frame.shape;
93 let Def::Enum(def) = shape.def else {
94 return Err(ReflectError::WasNotA {
95 expected: "enum",
96 actual: shape,
97 });
98 };
99
100 let index =
101 def.variants
102 .iter()
103 .position(|v| v.name == name)
104 .ok_or(ReflectError::FieldError {
105 shape,
106 field_error: FieldError::NoSuchField,
107 })?;
108
109 self.variant(index)
110 }
111
112 pub fn find_variant(&self, name: &str) -> Option<(usize, Variant)> {
123 let frame = self.frames.last()?;
124 if let Def::Enum(def) = frame.shape.def {
125 def.variants
126 .iter()
127 .enumerate()
128 .find(|(_, v)| v.name == name)
129 .map(|(i, &v)| (i, v))
130 } else {
131 None
132 }
133 }
134
135 pub fn selected_variant(&self) -> Option<Variant> {
142 let frame = self.frames.last()?;
143 frame.istate.variant
144 }
145}