facet_reflect/wip/
enum_.rs1use facet_core::{FieldError, Type, UserType, Variant};
2#[cfg(feature = "log")]
3use owo_colors::OwoColorize;
4
5use crate::trace;
6use crate::{ISet, ReflectError, Wip};
7
8impl<'facet, 'shape> Wip<'facet, 'shape> {
9 pub fn variant(mut self, index: usize) -> Result<Self, ReflectError<'shape>> {
20 let frame = self.frames.last_mut().unwrap();
21 let shape = frame.shape;
22 let Type::User(UserType::Enum(def)) = shape.ty 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 if let Some(discriminant) = variant.discriminant {
46 unsafe {
47 let data_ptr = frame.data.as_mut_byte_ptr();
48 match def.enum_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 => {
54 *(data_ptr as *mut usize) = discriminant as usize
55 }
56 facet_core::EnumRepr::I8 => *(data_ptr as *mut i8) = discriminant as i8,
57 facet_core::EnumRepr::I16 => *(data_ptr as *mut i16) = discriminant as i16,
58 facet_core::EnumRepr::I32 => *(data_ptr as *mut i32) = discriminant as i32,
59 facet_core::EnumRepr::I64 => *(data_ptr as *mut i64) = discriminant,
60 facet_core::EnumRepr::ISize => {
61 *(data_ptr as *mut isize) = discriminant as isize
62 }
63 facet_core::EnumRepr::RustNPO => (),
64 _ => {
65 *(data_ptr as *mut u32) = discriminant as u32;
67 }
68 }
69 }
70 } frame.istate.variant = Some(variant);
74
75 trace!(
76 "[{}] Selecting variant {} of {} with discriminant {:?}",
77 self.frames.len(),
78 variant.name.blue(),
79 shape.blue(),
80 variant.discriminant
81 );
82
83 Ok(self)
84 }
85
86 pub fn variant_named(self, name: &str) -> Result<Self, ReflectError<'shape>> {
97 let frame = self.frames.last().unwrap();
98 let shape = frame.shape;
99 let Type::User(UserType::Enum(def)) = shape.ty else {
100 return Err(ReflectError::WasNotA {
101 expected: "enum",
102 actual: shape,
103 });
104 };
105
106 let index =
107 def.variants
108 .iter()
109 .position(|v| v.name == name)
110 .ok_or(ReflectError::FieldError {
111 shape,
112 field_error: FieldError::NoSuchField,
113 })?;
114
115 self.variant(index)
116 }
117
118 pub fn find_variant(&self, name: &str) -> Option<(usize, Variant<'shape>)> {
129 let frame = self.frames.last()?;
130 if let Type::User(UserType::Enum(def)) = frame.shape.ty {
131 def.variants
132 .iter()
133 .enumerate()
134 .find(|(_, v)| v.name == name)
135 .map(|(i, &v)| (i, v))
136 } else {
137 None
138 }
139 }
140
141 pub fn selected_variant(&self) -> Option<Variant<'shape>> {
148 let frame = self.frames.last()?;
149 frame.istate.variant
150 }
151}