facet_reflect/peek/
struct_.rs1use facet_core::{Field, FieldError, FieldFlags, StructType};
2
3use crate::Peek;
4use alloc::{vec, vec::Vec};
5
6#[derive(Clone, Copy)]
8pub struct PeekStruct<'mem, 'facet, 'shape> {
9 pub(crate) value: Peek<'mem, 'facet, 'shape>,
11
12 pub(crate) ty: StructType<'shape>,
14}
15
16impl core::fmt::Debug for PeekStruct<'_, '_, '_> {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 f.debug_struct("PeekStruct").finish_non_exhaustive()
19 }
20}
21
22impl<'mem, 'facet, 'shape> PeekStruct<'mem, 'facet, 'shape> {
23 #[inline(always)]
25 pub fn ty(&self) -> &StructType {
26 &self.ty
27 }
28
29 #[inline(always)]
31 pub fn field_count(&self) -> usize {
32 self.ty.fields.len()
33 }
34
35 #[inline(always)]
37 pub fn field(&self, index: usize) -> Result<Peek<'mem, 'facet, 'shape>, FieldError> {
38 self.ty
39 .fields
40 .get(index)
41 .map(|field| unsafe {
42 let field_data = self.value.data().field(field.offset);
43 Peek::unchecked_new(field_data, field.shape())
44 })
45 .ok_or(FieldError::IndexOutOfBounds {
46 index,
47 bound: self.ty.fields.len(),
48 })
49 }
50
51 #[inline]
53 pub fn field_by_name(&self, name: &str) -> Result<Peek<'mem, 'facet, 'shape>, FieldError> {
54 for (i, field) in self.ty.fields.iter().enumerate() {
55 if field.name == name {
56 return self.field(i);
57 }
58 }
59 Err(FieldError::NoSuchField)
60 }
61}
62
63impl<'mem, 'facet, 'shape> HasFields<'mem, 'facet, 'shape> for PeekStruct<'mem, 'facet, 'shape> {
64 #[inline]
66 fn fields(
67 &self,
68 ) -> impl DoubleEndedIterator<Item = (Field<'shape>, Peek<'mem, 'facet, 'shape>)> {
69 (0..self.field_count()).filter_map(|i| {
70 let field = self.ty.fields.get(i).copied()?;
71 let value = self.field(i).ok()?;
72 Some((field, value))
73 })
74 }
75}
76
77pub trait HasFields<'mem, 'facet, 'shape> {
82 fn fields(
84 &self,
85 ) -> impl DoubleEndedIterator<Item = (Field<'shape>, Peek<'mem, 'facet, 'shape>)>;
86
87 fn fields_for_serialize(
89 &self,
90 ) -> impl DoubleEndedIterator<Item = (Field<'shape>, Peek<'mem, 'facet, 'shape>)> {
91 self.fields()
94 .filter(|(field, peek)| !unsafe { field.should_skip_serializing(peek.data()) })
95 .flat_map(move |(mut field, peek)| {
96 if field.flags.contains(FieldFlags::FLATTEN) {
97 let mut flattened = Vec::new();
98 if let Ok(struct_peek) = peek.into_struct() {
99 struct_peek
100 .fields_for_serialize()
101 .for_each(|item| flattened.push(item));
102 } else if let Ok(enum_peek) = peek.into_enum() {
103 field.name = enum_peek
117 .active_variant()
118 .expect("Failed to get active variant")
119 .name;
120 field.flattened = true;
121 flattened.push((field, peek));
122 } else {
123 panic!("cannot flatten a {}", field.shape())
125 }
126 flattened
127 } else {
128 vec![(field, peek)]
129 }
130 })
131 }
132}