facet_reflect/peek/
struct_.rs1use facet_core::{Field, FieldAttribute, FieldError, Struct};
2
3use crate::Peek;
4
5#[derive(Clone, Copy)]
7pub struct PeekStruct<'mem> {
8 pub(crate) value: Peek<'mem>,
10
11 pub(crate) def: Struct,
13}
14
15impl<'mem> PeekStruct<'mem> {
16 #[inline(always)]
18 pub fn def(&self) -> &Struct {
19 &self.def
20 }
21
22 #[inline(always)]
24 pub fn field_count(&self) -> usize {
25 self.def.fields.len()
26 }
27
28 #[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 #[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 #[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
65 #[inline]
67 pub fn fields_for_serialize(&self) -> impl Iterator<Item = (&'static Field, Peek<'mem>)> + '_ {
68 self.fields().filter(|(field, peek)| {
69 for attr in field.attributes {
70 match attr {
71 FieldAttribute::SkipSerializingIf(fn_ptr) => {
72 if unsafe { fn_ptr(peek.data()) } {
73 return false;
74 }
75 }
76 FieldAttribute::SkipSerializing => {
77 return false;
78 }
79 _ => {}
80 }
81 }
82 true
83 })
84 }
85}