facet_reflect/peek/
struct_.rs

1use facet_core::StructDef;
2
3use crate::{Peek, PeekValue};
4
5/// Lets you read from a struct (implements read-only struct operations)
6#[derive(Clone, Copy)]
7pub struct PeekStruct<'mem> {
8    value: PeekValue<'mem>,
9    // I suppose this could be a `&'static` as well, idk
10    def: StructDef,
11}
12
13impl<'mem> core::ops::Deref for PeekStruct<'mem> {
14    type Target = PeekValue<'mem>;
15
16    #[inline(always)]
17    fn deref(&self) -> &Self::Target {
18        &self.value
19    }
20}
21
22impl<'mem> PeekStruct<'mem> {
23    /// Create a new peek struct
24    pub(crate) fn new(value: PeekValue<'mem>, def: StructDef) -> Self {
25        Self { value, def }
26    }
27
28    /// Returns the number of fields in this struct
29    #[inline(always)]
30    pub fn field_count(&self) -> usize {
31        self.def.fields.len()
32    }
33
34    /// Returns the name of the field at the given index
35    #[inline(always)]
36    pub fn field_name(&self, index: usize) -> Option<&'static str> {
37        self.def.fields.get(index).map(|field| field.name)
38    }
39
40    /// Returns the value of the field at the given index
41    #[inline(always)]
42    pub fn field_value(&self, index: usize) -> Option<Peek<'mem>> {
43        self.def.fields.get(index).map(|field| unsafe {
44            let field_data = self.data().field(field.offset);
45            Peek::unchecked_new(field_data, field.shape)
46        })
47    }
48
49    /// Returns the value of the field with the given name
50    #[inline(always)]
51    pub fn get_field(&self, name: &str) -> Option<Peek<'mem>> {
52        self.def
53            .fields
54            .iter()
55            .position(|field| field.name == name)
56            .and_then(|index| self.field_value(index))
57    }
58
59    /// Iterates over all fields in this struct, providing both name and value
60    #[inline]
61    pub fn fields(&self) -> impl Iterator<Item = (&'static str, Peek<'mem>)> + '_ {
62        (0..self.field_count()).filter_map(|i| {
63            let name = self.field_name(i)?;
64            let value = self.field_value(i)?;
65            Some((name, value))
66        })
67    }
68
69    /// Returns the struct definition
70    #[inline(always)]
71    pub fn def(&self) -> &StructDef {
72        &self.def
73    }
74
75    /// Iterates over all fields in this struct, providing index, name, value, and the field definition
76    #[inline]
77    pub fn fields_with_metadata(
78        &self,
79    ) -> impl Iterator<Item = (usize, &'static str, Peek<'mem>, &'static facet_core::Field)> + '_
80    {
81        (0..self.field_count()).filter_map(|i| {
82            let name = self.field_name(i)?;
83            let value = self.field_value(i)?;
84            let field = &self.def.fields[i];
85            Some((i, name, value, field))
86        })
87    }
88}