Skip to main content

bevy_reflect/impls/alloc/collections/btree/
map.rs

1use crate::{
2    error::ReflectCloneError,
3    generics::{Generics, TypeParamInfo},
4    kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef},
5    map::{map_apply, map_partial_cmp, map_partial_eq, map_try_apply, Map, MapInfo},
6    prelude::*,
7    reflect::{impl_full_reflect, ApplyError},
8    type_info::{MaybeTyped, TypeInfo, Typed},
9    type_registry::{FromType, GetTypeRegistration, ReflectFromPtr, TypeRegistration},
10    utility::GenericTypeInfoCell,
11};
12use alloc::vec::Vec;
13use bevy_platform::prelude::*;
14use bevy_reflect_derive::impl_type_path;
15
16impl<K, V> Map for ::alloc::collections::BTreeMap<K, V>
17where
18    K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
19    V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
20{
21    fn get(&self, key: &dyn PartialReflect) -> Option<&dyn PartialReflect> {
22        key.try_downcast_ref::<K>()
23            .and_then(|key| Self::get(self, key))
24            .map(|value| value as &dyn PartialReflect)
25    }
26
27    fn get_mut(&mut self, key: &dyn PartialReflect) -> Option<&mut dyn PartialReflect> {
28        key.try_downcast_ref::<K>()
29            .and_then(move |key| Self::get_mut(self, key))
30            .map(|value| value as &mut dyn PartialReflect)
31    }
32
33    fn len(&self) -> usize {
34        Self::len(self)
35    }
36
37    fn iter(&self) -> Box<dyn Iterator<Item = (&dyn PartialReflect, &dyn PartialReflect)> + '_> {
38        Box::new(
39            self.iter()
40                .map(|(k, v)| (k as &dyn PartialReflect, v as &dyn PartialReflect)),
41        )
42    }
43
44    fn drain(&mut self) -> Vec<(Box<dyn PartialReflect>, Box<dyn PartialReflect>)> {
45        // BTreeMap doesn't have a `drain` function. See
46        // https://github.com/rust-lang/rust/issues/81074. So we have to fake one by popping
47        // elements off one at a time.
48        let mut result = Vec::with_capacity(self.len());
49        while let Some((k, v)) = self.pop_first() {
50            result.push((
51                Box::new(k) as Box<dyn PartialReflect>,
52                Box::new(v) as Box<dyn PartialReflect>,
53            ));
54        }
55        result
56    }
57
58    fn retain(&mut self, f: &mut dyn FnMut(&dyn PartialReflect, &mut dyn PartialReflect) -> bool) {
59        self.retain(move |k, v| f(k, v));
60    }
61
62    fn insert_boxed(
63        &mut self,
64        key: Box<dyn PartialReflect>,
65        value: Box<dyn PartialReflect>,
66    ) -> Option<Box<dyn PartialReflect>> {
67        let key = K::take_from_reflect(key).unwrap_or_else(|key| {
68            panic!(
69                "Attempted to insert invalid key of type {}.",
70                key.reflect_type_path()
71            )
72        });
73        let value = V::take_from_reflect(value).unwrap_or_else(|value| {
74            panic!(
75                "Attempted to insert invalid value of type {}.",
76                value.reflect_type_path()
77            )
78        });
79        self.insert(key, value)
80            .map(|old_value| Box::new(old_value) as Box<dyn PartialReflect>)
81    }
82
83    fn remove(&mut self, key: &dyn PartialReflect) -> Option<Box<dyn PartialReflect>> {
84        let mut from_reflect = None;
85        key.try_downcast_ref::<K>()
86            .or_else(|| {
87                from_reflect = K::from_reflect(key);
88                from_reflect.as_ref()
89            })
90            .and_then(|key| self.remove(key))
91            .map(|value| Box::new(value) as Box<dyn PartialReflect>)
92    }
93}
94
95impl<K, V> PartialReflect for ::alloc::collections::BTreeMap<K, V>
96where
97    K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
98    V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
99{
100    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
101        Some(<Self as Typed>::type_info())
102    }
103    #[inline]
104    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
105        self
106    }
107
108    fn as_partial_reflect(&self) -> &dyn PartialReflect {
109        self
110    }
111
112    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
113        self
114    }
115    #[inline]
116    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
117        Ok(self)
118    }
119
120    fn try_as_reflect(&self) -> Option<&dyn Reflect> {
121        Some(self)
122    }
123
124    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
125        Some(self)
126    }
127    fn reflect_kind(&self) -> ReflectKind {
128        ReflectKind::Map
129    }
130
131    fn reflect_ref(&self) -> ReflectRef<'_> {
132        ReflectRef::Map(self)
133    }
134
135    fn reflect_mut(&mut self) -> ReflectMut<'_> {
136        ReflectMut::Map(self)
137    }
138
139    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
140        ReflectOwned::Map(self)
141    }
142
143    fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
144        let mut map = Self::new();
145        for (key, value) in self.iter() {
146            let key = key.reflect_clone_and_take()?;
147            let value = value.reflect_clone_and_take()?;
148            map.insert(key, value);
149        }
150
151        Ok(Box::new(map))
152    }
153
154    fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
155        map_partial_eq(self, value)
156    }
157
158    fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
159        map_partial_cmp(self, value)
160    }
161
162    fn apply(&mut self, value: &dyn PartialReflect) {
163        map_apply(self, value);
164    }
165
166    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
167        map_try_apply(self, value)
168    }
169}
170
171impl_full_reflect!(
172    <K, V> for ::alloc::collections::BTreeMap<K, V>
173    where
174        K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
175        V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
176);
177
178impl<K, V> Typed for ::alloc::collections::BTreeMap<K, V>
179where
180    K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
181    V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
182{
183    fn type_info() -> &'static TypeInfo {
184        static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
185        CELL.get_or_insert::<Self, _>(|| {
186            TypeInfo::Map(
187                MapInfo::new::<Self, K, V>().with_generics(Generics::from_iter([
188                    TypeParamInfo::new::<K>("K"),
189                    TypeParamInfo::new::<V>("V"),
190                ])),
191            )
192        })
193    }
194}
195
196impl<K, V> GetTypeRegistration for ::alloc::collections::BTreeMap<K, V>
197where
198    K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
199    V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
200{
201    fn get_type_registration() -> TypeRegistration {
202        let mut registration = TypeRegistration::of::<Self>();
203        registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type());
204        registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type());
205        registration
206    }
207}
208
209impl<K, V> FromReflect for ::alloc::collections::BTreeMap<K, V>
210where
211    K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
212    V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
213{
214    fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
215        let ref_map = reflect.reflect_ref().as_map().ok()?;
216
217        let mut new_map = Self::new();
218
219        for (key, value) in ref_map.iter() {
220            let new_key = K::from_reflect(key)?;
221            let new_value = V::from_reflect(value)?;
222            new_map.insert(new_key, new_value);
223        }
224
225        Some(new_map)
226    }
227}
228
229impl_type_path!(::alloc::collections::BTreeMap<K, V>);
230#[cfg(feature = "functions")]
231crate::func::macros::impl_function_traits!(::alloc::collections::BTreeMap<K, V>;
232    <
233        K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord,
234        V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration
235    >
236);