facet_reflect/poke/
tuple.rs1use facet_core::{Facet, FieldError};
2
3use crate::{ReflectError, ReflectErrorKind, peek::TupleType};
4
5use super::Poke;
6
7pub struct PokeTuple<'mem, 'facet> {
12 pub(crate) value: Poke<'mem, 'facet>,
13 pub(crate) ty: TupleType,
14}
15
16impl<'mem, 'facet> core::fmt::Debug for PokeTuple<'mem, 'facet> {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 f.debug_struct("PokeTuple")
19 .field("type", &self.ty)
20 .finish_non_exhaustive()
21 }
22}
23
24impl<'mem, 'facet> PokeTuple<'mem, 'facet> {
25 fn err(&self, kind: ReflectErrorKind) -> ReflectError {
26 self.value.err(kind)
27 }
28
29 #[inline]
31 pub const fn len(&self) -> usize {
32 self.ty.fields.len()
33 }
34
35 #[inline]
37 pub const fn is_empty(&self) -> bool {
38 self.len() == 0
39 }
40
41 #[inline]
43 pub const fn ty(&self) -> TupleType {
44 self.ty
45 }
46
47 pub fn field(&self, index: usize) -> Option<crate::Peek<'_, 'facet>> {
49 let field = self.ty.fields.get(index)?;
50 let field_ptr = unsafe { self.value.data().field(field.offset) };
51 Some(unsafe { crate::Peek::unchecked_new(field_ptr, field.shape()) })
52 }
53
54 pub fn field_mut(&mut self, index: usize) -> Result<Poke<'_, 'facet>, ReflectError> {
56 let field = self.ty.fields.get(index).ok_or_else(|| {
57 self.err(ReflectErrorKind::FieldError {
58 shape: self.value.shape,
59 field_error: FieldError::IndexOutOfBounds {
60 index,
61 bound: self.ty.fields.len(),
62 },
63 })
64 })?;
65 let field_data = unsafe { self.value.data_mut().field(field.offset) };
66 Ok(unsafe { Poke::from_raw_parts(field_data, field.shape()) })
67 }
68
69 pub fn set_field<T: Facet<'facet>>(
76 &mut self,
77 index: usize,
78 value: T,
79 ) -> Result<(), ReflectError> {
80 if !self.value.shape.is_pod() {
81 return Err(self.err(ReflectErrorKind::NotPod {
82 shape: self.value.shape,
83 }));
84 }
85
86 let field = self.ty.fields.get(index).ok_or_else(|| {
87 self.err(ReflectErrorKind::FieldError {
88 shape: self.value.shape,
89 field_error: FieldError::IndexOutOfBounds {
90 index,
91 bound: self.ty.fields.len(),
92 },
93 })
94 })?;
95
96 let field_shape = field.shape();
97 if field_shape != T::SHAPE {
98 return Err(self.err(ReflectErrorKind::WrongShape {
99 expected: field_shape,
100 actual: T::SHAPE,
101 }));
102 }
103
104 unsafe {
105 let field_ptr = self.value.data_mut().field(field.offset);
106 field_shape.call_drop_in_place(field_ptr);
107 core::ptr::write(field_ptr.as_mut_byte_ptr() as *mut T, value);
108 }
109 Ok(())
110 }
111
112 #[inline]
114 pub const fn into_inner(self) -> Poke<'mem, 'facet> {
115 self.value
116 }
117
118 #[inline]
120 pub fn as_peek_tuple(&self) -> crate::PeekTuple<'_, 'facet> {
121 crate::PeekTuple {
122 value: self.value.as_peek(),
123 ty: self.ty,
124 }
125 }
126}