facet_reflect/poke/
struct_.rs1use facet_core::{Facet, FieldError, StructType};
2
3use crate::ReflectError;
4
5use super::Poke;
6
7pub struct PokeStruct<'mem, 'facet> {
9 pub(crate) value: Poke<'mem, 'facet>,
11
12 pub(crate) ty: StructType,
14}
15
16impl core::fmt::Debug for PokeStruct<'_, '_> {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 f.debug_struct("PokeStruct").finish_non_exhaustive()
19 }
20}
21
22impl<'mem, 'facet> PokeStruct<'mem, 'facet> {
23 #[inline(always)]
25 pub fn ty(&self) -> &StructType {
26 &self.ty
27 }
28
29 #[inline(always)]
31 pub fn field_count(&self) -> usize {
32 self.ty.fields.len()
33 }
34
35 pub fn field(&mut self, index: usize) -> Result<Poke<'_, 'facet>, ReflectError> {
41 let field = self.ty.fields.get(index).ok_or(ReflectError::FieldError {
42 shape: self.value.shape,
43 field_error: FieldError::IndexOutOfBounds {
44 index,
45 bound: self.ty.fields.len(),
46 },
47 })?;
48
49 let field_data = unsafe { self.value.data.field(field.offset) };
50 let field_shape = field.shape();
51
52 Ok(unsafe { Poke::from_raw_parts(field_data, field_shape) })
53 }
54
55 pub fn field_by_name(&mut self, name: &str) -> Result<Poke<'_, 'facet>, ReflectError> {
59 for (i, field) in self.ty.fields.iter().enumerate() {
60 if field.name == name {
61 return self.field(i);
62 }
63 }
64 Err(ReflectError::FieldError {
65 shape: self.value.shape,
66 field_error: FieldError::NoSuchField,
67 })
68 }
69
70 pub fn set_field<T: Facet<'facet>>(
78 &mut self,
79 index: usize,
80 value: T,
81 ) -> Result<(), ReflectError> {
82 if !self.value.shape.is_pod() {
84 return Err(ReflectError::NotPod {
85 shape: self.value.shape,
86 });
87 }
88
89 let field = self.ty.fields.get(index).ok_or(ReflectError::FieldError {
90 shape: self.value.shape,
91 field_error: FieldError::IndexOutOfBounds {
92 index,
93 bound: self.ty.fields.len(),
94 },
95 })?;
96
97 let field_shape = field.shape();
98 if field_shape != T::SHAPE {
99 return Err(ReflectError::WrongShape {
100 expected: field_shape,
101 actual: T::SHAPE,
102 });
103 }
104
105 unsafe {
106 let field_ptr = self.value.data.field(field.offset);
107 field_shape.call_drop_in_place(field_ptr);
109 core::ptr::write(field_ptr.as_mut_byte_ptr() as *mut T, value);
110 }
111
112 Ok(())
113 }
114
115 pub fn set_field_by_name<T: Facet<'facet>>(
119 &mut self,
120 name: &str,
121 value: T,
122 ) -> Result<(), ReflectError> {
123 for (i, field) in self.ty.fields.iter().enumerate() {
124 if field.name == name {
125 return self.set_field(i, value);
126 }
127 }
128 Err(ReflectError::FieldError {
129 shape: self.value.shape,
130 field_error: FieldError::NoSuchField,
131 })
132 }
133
134 pub fn peek_field(&self, index: usize) -> Result<crate::Peek<'_, 'facet>, FieldError> {
136 let field = self
137 .ty
138 .fields
139 .get(index)
140 .ok_or(FieldError::IndexOutOfBounds {
141 index,
142 bound: self.ty.fields.len(),
143 })?;
144
145 let field_data = unsafe { self.value.data.as_const().field(field.offset) };
146 Ok(unsafe { crate::Peek::unchecked_new(field_data, field.shape()) })
147 }
148
149 pub fn peek_field_by_name(&self, name: &str) -> Result<crate::Peek<'_, 'facet>, FieldError> {
151 for (i, field) in self.ty.fields.iter().enumerate() {
152 if field.name == name {
153 return self.peek_field(i);
154 }
155 }
156 Err(FieldError::NoSuchField)
157 }
158
159 #[inline]
161 pub fn into_inner(self) -> Poke<'mem, 'facet> {
162 self.value
163 }
164
165 #[inline]
167 pub fn as_peek_struct(&self) -> crate::PeekStruct<'_, 'facet> {
168 crate::PeekStruct {
169 value: self.value.as_peek(),
170 ty: self.ty,
171 }
172 }
173}
174
175