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 }
47
48 #[inline]
50 pub fn field_by_name(&self, name: &str) -> Result<Peek<'mem, 'facet_lifetime>, FieldError> {
51 for (i, field) in self.def.fields.iter().enumerate() {
52 if field.name == name {
53 return self.field(i);
54 }
55 }
56 Err(FieldError::NoSuchField)
57 }
58}
59
60impl<'mem, 'facet_lifetime> HasFields<'mem, 'facet_lifetime> for PeekStruct<'mem, 'facet_lifetime> {
61 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
62 (0..self.def.fields.len())
63 .filter_map(move |i| self.field(i).ok().map(|value| (self.def.fields[i], value)))
64 }
65}
66
67pub trait HasFields<'mem, 'facet_lifetime> {
72 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)>;
74
75 fn fields_for_serialize(
77 &self,
78 ) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
79 self.fields()
82 .filter(|(field, peek)| !unsafe { field.should_skip_serializing(peek.data()) })
83 .flat_map(|(mut field, peek)| {
84 if field.flags.contains(FieldFlags::FLATTEN) {
85 let mut flattened = Vec::new();
86 if let Ok(struct_peek) = peek.into_struct() {
87 struct_peek
88 .fields_for_serialize()
89 .for_each(|item| flattened.push(item));
90 } else if let Ok(enum_peek) = peek.into_enum() {
91 field.name = enum_peek.active_variant().name;
105 field.flattened = true;
106 flattened.push((field, peek));
107 } else {
108 panic!("cannot flatten a {}", field.shape())
110 }
111 flattened.into_iter()
112 } else {
113 vec![(field, peek)].into_iter()
114 }
115 })
116 }
117}