facet_reflect/peek/
struct_.rs1use facet_core::{Field, FieldError, FieldFlags, StructDef};
2
3use crate::Peek;
4use alloc::{vec, vec::Vec};
5
6#[derive(Clone, Copy)]
8pub struct PeekStruct<'mem, 'facet_lifetime> {
9 pub(crate) value: Peek<'mem, 'facet_lifetime>,
11
12 pub(crate) def: StructDef,
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_lifetime> PeekStruct<'mem, 'facet_lifetime> {
23 #[inline(always)]
25 pub fn def(&self) -> &StructDef {
26 &self.def
27 }
28
29 #[inline(always)]
31 pub fn field_count(&self) -> usize {
32 self.def.fields.len()
33 }
34
35 #[inline(always)]
37 pub fn field(&self, index: usize) -> Result<Peek<'mem, 'facet_lifetime>, FieldError> {
38 self.def
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.def.fields.len(),
48 })
49 }
50
51 #[inline]
53 pub fn field_by_name(&self, name: &str) -> Result<Peek<'mem, 'facet_lifetime>, FieldError> {
54 for (i, field) in self.def.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_lifetime> HasFields<'mem, 'facet_lifetime> for PeekStruct<'mem, 'facet_lifetime> {
64 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
65 (0..self.def.fields.len())
66 .filter_map(move |i| self.field(i).ok().map(|value| (self.def.fields[i], value)))
67 }
68}
69
70pub trait HasFields<'mem, 'facet_lifetime> {
75 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)>;
77
78 fn fields_for_serialize(
80 &self,
81 ) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
82 self.fields()
85 .filter(|(field, peek)| !unsafe { field.should_skip_serializing(peek.data()) })
86 .flat_map(|(mut field, peek)| {
87 if field.flags.contains(FieldFlags::FLATTEN) {
88 let mut flattened = Vec::new();
89 if let Ok(struct_peek) = peek.into_struct() {
90 struct_peek
91 .fields_for_serialize()
92 .for_each(|item| flattened.push(item));
93 } else if let Ok(enum_peek) = peek.into_enum() {
94 field.name = enum_peek.active_variant().name;
108 field.flattened = true;
109 flattened.push((field, peek));
110 } else {
111 panic!("cannot flatten a {}", field.shape())
113 }
114 flattened.into_iter()
115 } else {
116 vec![(field, peek)].into_iter()
117 }
118 })
119 }
120}