mirror_mirror/
struct_.rs

1use alloc::boxed::Box;
2use alloc::collections::BTreeMap;
3use alloc::string::String;
4use alloc::vec::Vec;
5use core::any::Any;
6use core::fmt;
7use core::iter::FusedIterator;
8
9use crate::iter::PairIterMut;
10use crate::type_info::graph::NodeId;
11use crate::type_info::graph::OpaqueNode;
12use crate::type_info::graph::TypeGraph;
13use crate::DescribeType;
14use crate::FromReflect;
15use crate::Reflect;
16use crate::ReflectMut;
17use crate::ReflectOwned;
18use crate::ReflectRef;
19use crate::Value;
20
21/// A reflected struct type.
22///
23/// Will be implemented by `#[derive(Reflect)]` on structs.
24pub trait Struct: Reflect {
25    fn field(&self, name: &str) -> Option<&dyn Reflect>;
26
27    fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
28
29    fn field_at(&self, index: usize) -> Option<&dyn Reflect>;
30
31    fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
32
33    fn name_at(&self, index: usize) -> Option<&str>;
34
35    fn fields(&self) -> Iter<'_>;
36
37    fn fields_mut(&mut self) -> PairIterMut<'_>;
38
39    fn fields_len(&self) -> usize;
40}
41
42impl fmt::Debug for dyn Struct {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        self.as_reflect().debug(f)
45    }
46}
47
48#[derive(Default, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
49#[cfg_attr(feature = "speedy", derive(speedy::Readable, speedy::Writable))]
50#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51pub struct StructValue {
52    field_names: Vec<String>,
53    // use a `BTreeMap` because `HashMap` isn't `serde::Serialize`
54    fields: BTreeMap<String, Value>,
55}
56
57impl StructValue {
58    pub fn new() -> Self {
59        Self::default()
60    }
61
62    pub fn with_capacity(capacity: usize) -> Self {
63        Self {
64            field_names: Vec::with_capacity(capacity),
65            // there is no `BTreeMap::with_capacity` :(
66            fields: BTreeMap::new(),
67        }
68    }
69
70    pub fn with_field(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
71        self.set_field(name, value);
72        self
73    }
74
75    pub fn set_field(&mut self, name: impl Into<String>, value: impl Into<Value>) {
76        let name = name.into();
77        if self.fields.insert(name.clone(), value.into()).is_none() {
78            self.field_names.push(name);
79        }
80    }
81}
82
83impl DescribeType for StructValue {
84    fn build(graph: &mut TypeGraph) -> NodeId {
85        graph.get_or_build_node_with::<Self, _>(|graph| {
86            OpaqueNode::new::<Self>(Default::default(), graph)
87        })
88    }
89}
90
91impl Reflect for StructValue {
92    trivial_reflect_methods!();
93
94    fn patch(&mut self, value: &dyn Reflect) {
95        if let Some(struct_) = value.reflect_ref().as_struct() {
96            for (name, value) in self.fields_mut() {
97                if let Some(new_value) = struct_.field(name) {
98                    value.patch(new_value);
99                }
100            }
101        }
102    }
103
104    fn to_value(&self) -> Value {
105        self.clone().into()
106    }
107
108    fn clone_reflect(&self) -> Box<dyn Reflect> {
109        Box::new(self.clone())
110    }
111
112    fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        if f.alternate() {
114            write!(f, "{self:#?}")
115        } else {
116            write!(f, "{self:?}")
117        }
118    }
119
120    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
121        ReflectOwned::Struct(self)
122    }
123
124    fn reflect_ref(&self) -> ReflectRef<'_> {
125        ReflectRef::Struct(self)
126    }
127
128    fn reflect_mut(&mut self) -> ReflectMut<'_> {
129        ReflectMut::Struct(self)
130    }
131}
132
133impl Struct for StructValue {
134    fn field(&self, name: &str) -> Option<&dyn Reflect> {
135        Some(self.fields.get(name)?)
136    }
137
138    fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect> {
139        Some(self.fields.get_mut(name)?)
140    }
141
142    fn fields(&self) -> Iter<'_> {
143        Iter::new(self)
144    }
145
146    fn fields_mut(&mut self) -> PairIterMut<'_> {
147        let iter = self
148            .fields
149            .iter_mut()
150            .map(|(key, value)| (&**key, value.as_reflect_mut()));
151        Box::new(iter)
152    }
153
154    fn fields_len(&self) -> usize {
155        self.field_names.len()
156    }
157
158    fn field_at(&self, index: usize) -> Option<&dyn Reflect> {
159        let key = self.field_names.get(index)?;
160        Some(self.fields.get(key)?)
161    }
162
163    fn name_at(&self, index: usize) -> Option<&str> {
164        self.field_names.get(index).map(|s| &**s)
165    }
166
167    fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
168        let key = self.field_names.get(index)?;
169        Some(self.fields.get_mut(key)?)
170    }
171}
172
173impl FromReflect for StructValue {
174    fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
175        let struct_ = reflect.reflect_ref().as_struct()?;
176        let this = struct_
177            .fields()
178            .fold(StructValue::default(), |builder, (name, value)| {
179                builder.with_field(name, value.to_value())
180            });
181        Some(this)
182    }
183}
184
185impl<S, V> FromIterator<(S, V)> for StructValue
186where
187    S: Into<String>,
188    V: Reflect,
189{
190    fn from_iter<T>(iter: T) -> Self
191    where
192        T: IntoIterator<Item = (S, V)>,
193    {
194        let mut out = Self::default();
195        for (name, value) in iter {
196            out.set_field(name, value.to_value());
197        }
198        out
199    }
200}
201
202#[derive(Debug)]
203pub struct Iter<'a> {
204    struct_: &'a dyn Struct,
205    index: usize,
206}
207
208impl<'a> Iter<'a> {
209    pub fn new(struct_: &'a dyn Struct) -> Self {
210        Self { struct_, index: 0 }
211    }
212}
213
214impl<'a> Iterator for Iter<'a> {
215    type Item = (&'a str, &'a dyn Reflect);
216
217    fn next(&mut self) -> Option<Self::Item> {
218        let name = self.struct_.name_at(self.index)?;
219        let value = self.struct_.field_at(self.index)?;
220        self.index += 1;
221        Some((name, value))
222    }
223}
224
225impl<'a> ExactSizeIterator for Iter<'a> {
226    fn len(&self) -> usize {
227        self.struct_.fields_len()
228    }
229}
230
231impl<'a> FusedIterator for Iter<'a> {}