facet_reflect/peek/
struct_.rs

1use facet_core::{FieldError, StructType};
2
3use crate::Peek;
4
5use super::{FieldIter, HasFields};
6
7/// Lets you read from a struct (implements read-only struct operations)
8#[derive(Clone, Copy)]
9pub struct PeekStruct<'mem, 'facet, 'shape> {
10    /// the underlying value
11    pub(crate) value: Peek<'mem, 'facet, 'shape>,
12
13    /// the definition of the struct!
14    pub(crate) ty: StructType<'shape>,
15}
16
17impl core::fmt::Debug for PeekStruct<'_, '_, '_> {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        f.debug_struct("PeekStruct").finish_non_exhaustive()
20    }
21}
22
23impl<'mem, 'facet, 'shape> PeekStruct<'mem, 'facet, 'shape> {
24    /// Returns the struct definition
25    #[inline(always)]
26    pub fn ty(&self) -> &StructType {
27        &self.ty
28    }
29
30    /// Returns the number of fields in this struct
31    #[inline(always)]
32    pub fn field_count(&self) -> usize {
33        self.ty.fields.len()
34    }
35
36    /// Returns the value of the field at the given index
37    #[inline(always)]
38    pub fn field(&self, index: usize) -> Result<Peek<'mem, 'facet, 'shape>, FieldError> {
39        self.ty
40            .fields
41            .get(index)
42            .map(|field| unsafe {
43                let field_data = self.value.data().field(field.offset);
44                Peek::unchecked_new(field_data, field.shape())
45            })
46            .ok_or(FieldError::IndexOutOfBounds {
47                index,
48                bound: self.ty.fields.len(),
49            })
50    }
51
52    /// Gets the value of the field with the given name
53    #[inline]
54    pub fn field_by_name(&self, name: &str) -> Result<Peek<'mem, 'facet, 'shape>, FieldError> {
55        for (i, field) in self.ty.fields.iter().enumerate() {
56            if field.name == name {
57                return self.field(i);
58            }
59        }
60        Err(FieldError::NoSuchField)
61    }
62}
63
64impl<'mem, 'facet, 'shape> HasFields<'mem, 'facet, 'shape> for PeekStruct<'mem, 'facet, 'shape> {
65    /// Iterates over all fields in this struct, providing both name and value
66    #[inline]
67    fn fields(&self) -> FieldIter<'mem, 'facet, 'shape> {
68        FieldIter::new_struct(*self)
69    }
70}