mirror_mirror/
get_field.rs

1use alloc::borrow::ToOwned;
2use alloc::string::String;
3
4use crate::Array;
5use crate::Enum;
6use crate::Map;
7use crate::Reflect;
8use crate::ReflectMut;
9use crate::ReflectRef;
10use crate::Struct;
11use crate::Tuple;
12use crate::TupleStruct;
13use crate::Value;
14
15/// Helper trait for accessing and downcasting fields on reflected values.
16pub trait GetField<'a, K, M> {
17    fn get_field<T>(self, key: K) -> Option<&'a T>
18    where
19        T: Reflect;
20}
21
22/// Helper trait for mutably accessing and downcasting fields on reflected values.
23pub trait GetFieldMut<'a, K, M> {
24    fn get_field_mut<T>(self, key: K) -> Option<&'a mut T>
25    where
26        T: Reflect;
27}
28
29impl<'a, R, K, M> GetField<'a, K, M> for &'a mut R
30where
31    R: ?Sized,
32    &'a R: GetField<'a, K, M>,
33{
34    fn get_field<T>(self, key: K) -> Option<&'a T>
35    where
36        T: Reflect,
37    {
38        <&R as GetField<_, _>>::get_field(self, key)
39    }
40}
41
42impl<'a> GetField<'a, &str, private::Value> for &'a Value {
43    fn get_field<T>(self, key: &str) -> Option<&'a T>
44    where
45        T: Reflect,
46    {
47        match self.reflect_ref() {
48            ReflectRef::Struct(inner) => inner.get_field(key),
49            ReflectRef::Enum(inner) => inner.get_field(key),
50            ReflectRef::Map(inner) => inner.get_field(key),
51            ReflectRef::TupleStruct(_)
52            | ReflectRef::Tuple(_)
53            | ReflectRef::List(_)
54            | ReflectRef::Array(_)
55            | ReflectRef::Opaque(_)
56            | ReflectRef::Scalar(_) => None,
57        }
58    }
59}
60
61impl<'a> GetFieldMut<'a, &str, private::Value> for &'a mut Value {
62    fn get_field_mut<T>(self, key: &str) -> Option<&'a mut T>
63    where
64        T: Reflect,
65    {
66        match self.reflect_mut() {
67            ReflectMut::Struct(inner) => inner.get_field_mut(key),
68            ReflectMut::Enum(inner) => inner.get_field_mut(key),
69            ReflectMut::Map(inner) => inner.get_field_mut(key),
70            ReflectMut::TupleStruct(_)
71            | ReflectMut::Tuple(_)
72            | ReflectMut::List(_)
73            | ReflectMut::Array(_)
74            | ReflectMut::Opaque(_)
75            | ReflectMut::Scalar(_) => None,
76        }
77    }
78}
79
80impl<'a, K> GetField<'a, K, private::Value> for &'a Value
81where
82    K: Reflect,
83{
84    fn get_field<T>(self, key: K) -> Option<&'a T>
85    where
86        T: Reflect,
87    {
88        if let Some(&key) = key.as_any().downcast_ref::<usize>() {
89            match self.reflect_ref() {
90                ReflectRef::TupleStruct(inner) => inner.get_field(key),
91                ReflectRef::Tuple(inner) => inner.get_field(key),
92                ReflectRef::Enum(inner) => inner.get_field(key),
93                ReflectRef::Array(inner) => inner.get_field(key),
94                ReflectRef::List(inner) => inner.get_field(key),
95                ReflectRef::Map(inner) => inner.get_field(key),
96                ReflectRef::Struct(_) | ReflectRef::Scalar(_) | ReflectRef::Opaque(_) => None,
97            }
98        } else if let Some(key) = key.as_any().downcast_ref::<String>() {
99            match self.reflect_ref() {
100                ReflectRef::Map(inner) => inner.get_field(key.to_owned()),
101                ReflectRef::Struct(inner) => inner.get_field(key),
102                ReflectRef::TupleStruct(_)
103                | ReflectRef::Tuple(_)
104                | ReflectRef::Enum(_)
105                | ReflectRef::List(_)
106                | ReflectRef::Array(_)
107                | ReflectRef::Opaque(_)
108                | ReflectRef::Scalar(_) => None,
109            }
110        } else {
111            match self.reflect_ref() {
112                ReflectRef::Map(inner) => inner.get_field(key),
113                ReflectRef::TupleStruct(_)
114                | ReflectRef::Tuple(_)
115                | ReflectRef::Enum(_)
116                | ReflectRef::Array(_)
117                | ReflectRef::List(_)
118                | ReflectRef::Struct(_)
119                | ReflectRef::Opaque(_)
120                | ReflectRef::Scalar(_) => None,
121            }
122        }
123    }
124}
125
126impl<'a, K> GetFieldMut<'a, K, private::Value> for &'a mut Value
127where
128    K: Reflect,
129{
130    fn get_field_mut<T>(self, key: K) -> Option<&'a mut T>
131    where
132        T: Reflect,
133    {
134        if let Some(&key) = key.as_any().downcast_ref::<usize>() {
135            match self.reflect_mut() {
136                ReflectMut::TupleStruct(inner) => inner.get_field_mut(key),
137                ReflectMut::Tuple(inner) => inner.get_field_mut(key),
138                ReflectMut::Enum(inner) => inner.get_field_mut(key),
139                ReflectMut::List(inner) => inner.get_field_mut(key),
140                ReflectMut::Array(inner) => inner.get_field_mut(key),
141                ReflectMut::Map(inner) => inner.get_field_mut(key),
142                ReflectMut::Struct(_) | ReflectMut::Scalar(_) | ReflectMut::Opaque(_) => None,
143            }
144        } else if let Some(key) = key.as_any().downcast_ref::<String>() {
145            match self.reflect_mut() {
146                ReflectMut::Map(inner) => inner.get_field_mut(key.to_owned()),
147                ReflectMut::Struct(inner) => inner.get_field_mut(key),
148                ReflectMut::TupleStruct(_)
149                | ReflectMut::Tuple(_)
150                | ReflectMut::Enum(_)
151                | ReflectMut::List(_)
152                | ReflectMut::Array(_)
153                | ReflectMut::Opaque(_)
154                | ReflectMut::Scalar(_) => None,
155            }
156        } else {
157            match self.reflect_mut() {
158                ReflectMut::Map(inner) => inner.get_field_mut(key),
159                ReflectMut::TupleStruct(_)
160                | ReflectMut::Tuple(_)
161                | ReflectMut::Enum(_)
162                | ReflectMut::List(_)
163                | ReflectMut::Array(_)
164                | ReflectMut::Struct(_)
165                | ReflectMut::Opaque(_)
166                | ReflectMut::Scalar(_) => None,
167            }
168        }
169    }
170}
171
172impl<'a, R> GetField<'a, &str, private::Struct> for &'a R
173where
174    R: Struct + ?Sized,
175{
176    fn get_field<T>(self, key: &str) -> Option<&'a T>
177    where
178        T: Reflect,
179    {
180        self.field(key)?.downcast_ref()
181    }
182}
183
184impl<'a, R> GetFieldMut<'a, &str, private::Struct> for &'a mut R
185where
186    R: Struct + ?Sized,
187{
188    fn get_field_mut<T>(self, key: &str) -> Option<&'a mut T>
189    where
190        T: Reflect,
191    {
192        self.field_mut(key)?.downcast_mut()
193    }
194}
195
196impl<'a, R> GetField<'a, usize, private::TupleStruct> for &'a R
197where
198    R: TupleStruct + ?Sized,
199{
200    fn get_field<T>(self, key: usize) -> Option<&'a T>
201    where
202        T: Reflect,
203    {
204        self.field_at(key)?.downcast_ref()
205    }
206}
207
208impl<'a, R> GetFieldMut<'a, usize, private::TupleStruct> for &'a mut R
209where
210    R: TupleStruct + ?Sized,
211{
212    fn get_field_mut<T>(self, key: usize) -> Option<&'a mut T>
213    where
214        T: Reflect,
215    {
216        self.field_at_mut(key)?.downcast_mut()
217    }
218}
219
220impl<'a, R> GetField<'a, &str, private::Enum> for &'a R
221where
222    R: Enum + ?Sized,
223{
224    fn get_field<T>(self, key: &str) -> Option<&'a T>
225    where
226        T: Reflect,
227    {
228        self.field(key)?.downcast_ref()
229    }
230}
231
232impl<'a, R> GetFieldMut<'a, &str, private::Enum> for &'a mut R
233where
234    R: Enum + ?Sized,
235{
236    fn get_field_mut<T>(self, key: &str) -> Option<&'a mut T>
237    where
238        T: Reflect,
239    {
240        self.field_mut(key)?.downcast_mut()
241    }
242}
243
244impl<'a, R> GetField<'a, usize, private::Enum> for &'a R
245where
246    R: Enum + ?Sized,
247{
248    fn get_field<T>(self, key: usize) -> Option<&'a T>
249    where
250        T: Reflect,
251    {
252        self.field_at(key)?.downcast_ref()
253    }
254}
255
256impl<'a, R> GetFieldMut<'a, usize, private::Enum> for &'a mut R
257where
258    R: Enum + ?Sized,
259{
260    fn get_field_mut<T>(self, key: usize) -> Option<&'a mut T>
261    where
262        T: Reflect,
263    {
264        self.field_at_mut(key)?.downcast_mut()
265    }
266}
267
268impl<'a, R> GetField<'a, usize, private::Tuple> for &'a R
269where
270    R: Tuple + ?Sized,
271{
272    fn get_field<T>(self, key: usize) -> Option<&'a T>
273    where
274        T: Reflect,
275    {
276        self.field_at(key)?.downcast_ref()
277    }
278}
279
280impl<'a, R> GetFieldMut<'a, usize, private::Tuple> for &'a mut R
281where
282    R: Tuple + ?Sized,
283{
284    fn get_field_mut<T>(self, key: usize) -> Option<&'a mut T>
285    where
286        T: Reflect,
287    {
288        self.field_at_mut(key)?.downcast_mut()
289    }
290}
291
292// we don't need to implement this for `R: List` because `List` is a subtrait of `Array`
293impl<'a, R> GetField<'a, usize, private::Array> for &'a R
294where
295    R: Array + ?Sized,
296{
297    fn get_field<T>(self, key: usize) -> Option<&'a T>
298    where
299        T: Reflect,
300    {
301        self.get(key)?.downcast_ref()
302    }
303}
304
305impl<'a, R> GetFieldMut<'a, usize, private::Array> for &'a mut R
306where
307    R: Array + ?Sized,
308{
309    fn get_field_mut<T>(self, key: usize) -> Option<&'a mut T>
310    where
311        T: Reflect,
312    {
313        self.get_mut(key)?.downcast_mut()
314    }
315}
316
317impl<'a, R, K> GetField<'a, K, private::Map> for &'a R
318where
319    R: Map + ?Sized,
320    K: Reflect,
321{
322    fn get_field<T>(self, key: K) -> Option<&'a T>
323    where
324        T: Reflect,
325    {
326        self.get(&key)?.downcast_ref()
327    }
328}
329
330impl<'a, R, K> GetFieldMut<'a, K, private::Map> for &'a mut R
331where
332    R: Map + ?Sized,
333    K: Reflect,
334{
335    fn get_field_mut<T>(self, key: K) -> Option<&'a mut T>
336    where
337        T: Reflect,
338    {
339        self.get_mut(&key)?.downcast_mut()
340    }
341}
342
343impl<'a, R> GetField<'a, &str, private::Map> for &'a R
344where
345    R: Map + ?Sized,
346{
347    fn get_field<T>(self, key: &str) -> Option<&'a T>
348    where
349        T: Reflect,
350    {
351        self.get(&key.to_owned())?.downcast_ref()
352    }
353}
354
355impl<'a, R> GetFieldMut<'a, &str, private::Map> for &'a mut R
356where
357    R: Map + ?Sized,
358{
359    fn get_field_mut<T>(self, key: &str) -> Option<&'a mut T>
360    where
361        T: Reflect,
362    {
363        self.get_mut(&key.to_owned())?.downcast_mut()
364    }
365}
366
367mod private {
368    #![allow(missing_debug_implementations)]
369
370    /// Types used to disambiguate otherwise overlapping trait impls
371
372    pub struct Struct;
373    pub struct TupleStruct;
374    pub struct Enum;
375    pub struct Tuple;
376    pub struct Array;
377    pub struct Map;
378    pub struct Value;
379}