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
21pub 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 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 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> {}