facet_reflect/peek/
struct_.rs

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