facet_reflect/poke/
struct_.rs1use facet_core::{Facet, FieldError, StructType};
2use facet_path::Path;
3
4use crate::{ReflectError, ReflectErrorKind};
5
6use super::Poke;
7
8pub struct PokeStruct<'mem, 'facet> {
10 pub(crate) value: Poke<'mem, 'facet>,
12
13 pub(crate) ty: StructType,
15}
16
17impl core::fmt::Debug for PokeStruct<'_, '_> {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 f.debug_struct("PokeStruct").finish_non_exhaustive()
20 }
21}
22
23impl<'mem, 'facet> PokeStruct<'mem, 'facet> {
24 fn err(&self, kind: ReflectErrorKind) -> ReflectError {
25 ReflectError::new(kind, Path::new(self.value.shape))
26 }
27
28 #[inline(always)]
30 pub const fn ty(&self) -> &StructType {
31 &self.ty
32 }
33
34 #[inline(always)]
36 pub const fn field_count(&self) -> usize {
37 self.ty.fields.len()
38 }
39
40 pub fn field(&mut self, index: usize) -> Result<Poke<'_, 'facet>, ReflectError> {
46 let field = self.ty.fields.get(index).ok_or_else(|| {
47 self.err(ReflectErrorKind::FieldError {
48 shape: self.value.shape,
49 field_error: FieldError::IndexOutOfBounds {
50 index,
51 bound: self.ty.fields.len(),
52 },
53 })
54 })?;
55
56 let field_data = unsafe { self.value.data.field(field.offset) };
57 let field_shape = field.shape();
58
59 Ok(unsafe { Poke::from_raw_parts(field_data, field_shape) })
60 }
61
62 pub fn field_by_name(&mut self, name: &str) -> Result<Poke<'_, 'facet>, ReflectError> {
66 for (i, field) in self.ty.fields.iter().enumerate() {
67 if field.name == name {
68 return self.field(i);
69 }
70 }
71 Err(self.err(ReflectErrorKind::FieldError {
72 shape: self.value.shape,
73 field_error: FieldError::NoSuchField,
74 }))
75 }
76
77 pub fn set_field<T: Facet<'facet>>(
85 &mut self,
86 index: usize,
87 value: T,
88 ) -> Result<(), ReflectError> {
89 if !self.value.shape.is_pod() {
91 return Err(self.err(ReflectErrorKind::NotPod {
92 shape: self.value.shape,
93 }));
94 }
95
96 let field = self.ty.fields.get(index).ok_or_else(|| {
97 self.err(ReflectErrorKind::FieldError {
98 shape: self.value.shape,
99 field_error: FieldError::IndexOutOfBounds {
100 index,
101 bound: self.ty.fields.len(),
102 },
103 })
104 })?;
105
106 let field_shape = field.shape();
107 if field_shape != T::SHAPE {
108 return Err(self.err(ReflectErrorKind::WrongShape {
109 expected: field_shape,
110 actual: T::SHAPE,
111 }));
112 }
113
114 unsafe {
115 let field_ptr = self.value.data.field(field.offset);
116 field_shape.call_drop_in_place(field_ptr);
118 core::ptr::write(field_ptr.as_mut_byte_ptr() as *mut T, value);
119 }
120
121 Ok(())
122 }
123
124 pub fn set_field_by_name<T: Facet<'facet>>(
128 &mut self,
129 name: &str,
130 value: T,
131 ) -> Result<(), ReflectError> {
132 for (i, field) in self.ty.fields.iter().enumerate() {
133 if field.name == name {
134 return self.set_field(i, value);
135 }
136 }
137 Err(self.err(ReflectErrorKind::FieldError {
138 shape: self.value.shape,
139 field_error: FieldError::NoSuchField,
140 }))
141 }
142
143 pub fn peek_field(&self, index: usize) -> Result<crate::Peek<'_, 'facet>, FieldError> {
145 let field = self
146 .ty
147 .fields
148 .get(index)
149 .ok_or(FieldError::IndexOutOfBounds {
150 index,
151 bound: self.ty.fields.len(),
152 })?;
153
154 let field_data = unsafe { self.value.data.as_const().field(field.offset) };
155 Ok(unsafe { crate::Peek::unchecked_new(field_data, field.shape()) })
156 }
157
158 pub fn peek_field_by_name(&self, name: &str) -> Result<crate::Peek<'_, 'facet>, FieldError> {
160 for (i, field) in self.ty.fields.iter().enumerate() {
161 if field.name == name {
162 return self.peek_field(i);
163 }
164 }
165 Err(FieldError::NoSuchField)
166 }
167
168 #[inline]
170 pub const fn into_inner(self) -> Poke<'mem, 'facet> {
171 self.value
172 }
173
174 #[inline]
176 pub fn as_peek_struct(&self) -> crate::PeekStruct<'_, 'facet> {
177 crate::PeekStruct {
178 value: self.value.as_peek(),
179 ty: self.ty,
180 }
181 }
182}
183
184