facet_reflect/peek/
struct_.rs1use facet_core::{Field, FieldAttribute, FieldError, FieldFlags, StructDef};
2
3use crate::Peek;
4
5#[derive(Clone, Copy)]
7pub struct PeekStruct<'mem, 'facet_lifetime> {
8 pub(crate) value: Peek<'mem, 'facet_lifetime>,
10
11 pub(crate) def: StructDef,
13}
14
15impl<'mem, 'facet_lifetime> PeekStruct<'mem, 'facet_lifetime> {
16 #[inline(always)]
18 pub fn def(&self) -> &StructDef {
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, 'facet_lifetime>, 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::unchecked_new(field_data, field.shape())
37 })
38 .ok_or(FieldError::IndexOutOfBounds)
39 }
40
41 #[inline]
43 pub fn field_by_name(&self, name: &str) -> Result<Peek<'mem, 'facet_lifetime>, FieldError> {
44 for (i, field) in self.def.fields.iter().enumerate() {
45 if field.name == name {
46 return self.field(i);
47 }
48 }
49 Err(FieldError::NoSuchField)
50 }
51
52 #[inline]
54 pub fn fields(
55 &self,
56 ) -> impl Iterator<Item = (&'static Field, Peek<'mem, 'facet_lifetime>)> + '_ {
57 (0..self.field_count()).filter_map(|i| {
58 let field = self.def.fields.get(i)?;
59 let value = self.field(i).ok()?;
60 Some((field, value))
61 })
62 }
63
64 #[inline]
66 pub fn fields_for_serialize(
67 &self,
68 ) -> impl Iterator<Item = (&'static Field, Peek<'mem, 'facet_lifetime>)> + '_ {
69 self.fields().filter(|(field, peek)| {
70 if field.flags.contains(FieldFlags::SKIP_SERIALIZING) {
71 return false;
72 }
73
74 for attr in field.attributes {
75 if let FieldAttribute::SkipSerializingIf(fn_ptr) = attr {
76 if unsafe { fn_ptr(peek.data()) } {
77 return false;
78 }
79 }
80 }
81 true
82 })
83 }
84}