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_lifetime> {
9 pub(crate) value: Peek<'mem, 'facet_lifetime>,
11
12 pub(crate) ty: StructType,
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 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_lifetime>, 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_lifetime>, 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_lifetime> HasFields<'mem, 'facet_lifetime> for PeekStruct<'mem, 'facet_lifetime> {
64 #[inline]
66 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
67 (0..self.field_count()).filter_map(|i| {
68 let field = self.ty.fields.get(i).copied()?;
69 let value = self.field(i).ok()?;
70 Some((field, value))
71 })
72 }
73}
74
75pub trait HasFields<'mem, 'facet_lifetime> {
80 fn fields(&self) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)>;
82
83 fn fields_for_serialize(
85 &self,
86 ) -> impl DoubleEndedIterator<Item = (Field, Peek<'mem, 'facet_lifetime>)> {
87 self.fields()
90 .filter(|(field, peek)| !unsafe { field.should_skip_serializing(peek.data()) })
91 .flat_map(|(mut field, peek)| {
92 if field.flags.contains(FieldFlags::FLATTEN) {
93 let mut flattened = Vec::new();
94 if let Ok(struct_peek) = peek.into_struct() {
95 struct_peek
96 .fields_for_serialize()
97 .for_each(|item| flattened.push(item));
98 } else if let Ok(enum_peek) = peek.into_enum() {
99 field.name = enum_peek
113 .active_variant()
114 .expect("Failed to get active variant")
115 .name;
116 field.flattened = true;
117 flattened.push((field, peek));
118 } else {
119 panic!("cannot flatten a {}", field.shape())
121 }
122 flattened.into_iter()
123 } else {
124 vec![(field, peek)].into_iter()
125 }
126 })
127 }
128}