diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 6db72df19354e..f94029bf9c0fa 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -192,15 +192,9 @@ impl DynamicArray { } } + #[deprecated(since = "0.15.0", note = "use from_iter")] pub fn from_vec(values: Vec) -> Self { - Self { - represented_type: None, - values: values - .into_iter() - .map(|field| Box::new(field) as Box) - .collect::>() - .into_boxed_slice(), - } + Self::from_iter(values) } /// Sets the [type] to be represented by this `DynamicArray`. @@ -358,6 +352,42 @@ impl Array for DynamicArray { } } +impl FromIterator> for DynamicArray { + fn from_iter>>(values: I) -> Self { + Self { + represented_type: None, + values: values.into_iter().collect::>().into_boxed_slice(), + } + } +} + +impl FromIterator for DynamicArray { + fn from_iter>(values: I) -> Self { + values + .into_iter() + .map(|value| Box::new(value).into_reflect()) + .collect() + } +} + +impl IntoIterator for DynamicArray { + type Item = Box; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.values.into_vec().into_iter() + } +} + +impl<'a> IntoIterator for &'a DynamicArray { + type Item = &'a dyn Reflect; + type IntoIter = ArrayIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + impl_type_path!((in bevy_reflect) DynamicArray); impl_function_traits!(DynamicArray); /// An iterator over an [`Array`]. diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index dcd77bb214aed..8d08bdaf803b6 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1088,7 +1088,7 @@ mod tests { }); foo_patch.insert("g", composite); - let array = DynamicArray::from_vec(vec![2u32, 2u32]); + let array = DynamicArray::from_iter([2u32, 2u32]); foo_patch.insert("h", array); foo.apply(&foo_patch); diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index c73baab3299b9..e1b91316b5092 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -378,6 +378,24 @@ impl Debug for DynamicList { } } +impl FromIterator> for DynamicList { + fn from_iter>>(values: I) -> Self { + Self { + represented_type: None, + values: values.into_iter().collect(), + } + } +} + +impl FromIterator for DynamicList { + fn from_iter>(values: I) -> Self { + values + .into_iter() + .map(|field| Box::new(field).into_reflect()) + .collect() + } +} + impl IntoIterator for DynamicList { type Item = Box; type IntoIter = std::vec::IntoIter; @@ -387,6 +405,15 @@ impl IntoIterator for DynamicList { } } +impl<'a> IntoIterator for &'a DynamicList { + type Item = &'a dyn Reflect; + type IntoIter = ListIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + /// An iterator over an [`List`]. pub struct ListIter<'a> { list: &'a dyn List, diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 844be9a2476be..c22b39307639a 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -455,6 +455,26 @@ impl<'a> Iterator for MapIter<'a> { } } +impl FromIterator<(Box, Box)> for DynamicMap { + fn from_iter, Box)>>(items: I) -> Self { + let mut map = Self::default(); + for (key, value) in items.into_iter() { + map.insert_boxed(key, value); + } + map + } +} + +impl FromIterator<(K, V)> for DynamicMap { + fn from_iter>(items: I) -> Self { + let mut map = Self::default(); + for (key, value) in items.into_iter() { + map.insert(key, value); + } + map + } +} + impl IntoIterator for DynamicMap { type Item = (Box, Box); type IntoIter = std::vec::IntoIter; @@ -464,6 +484,15 @@ impl IntoIterator for DynamicMap { } } +impl<'a> IntoIterator for &'a DynamicMap { + type Item = (&'a dyn Reflect, &'a dyn Reflect); + type IntoIter = MapIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + impl<'a> ExactSizeIterator for MapIter<'a> {} /// Compares a [`Map`] with a [`Reflect`] value. diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 92cba76baa6aa..b36bf3748807d 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -508,6 +508,39 @@ impl Debug for DynamicStruct { } } +impl<'a, N> FromIterator<(N, Box)> for DynamicStruct +where + N: Into>, +{ + /// Create a dynamic struct that doesn't represent a type from the + /// field name, field value pairs. + fn from_iter)>>(fields: I) -> Self { + let mut dynamic_struct = Self::default(); + for (name, value) in fields.into_iter() { + dynamic_struct.insert_boxed(name, value); + } + dynamic_struct + } +} + +impl IntoIterator for DynamicStruct { + type Item = Box; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.fields.into_iter() + } +} + +impl<'a> IntoIterator for &'a DynamicStruct { + type Item = &'a dyn Reflect; + type IntoIter = FieldIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_fields() + } +} + /// Compares a [`Struct`] with a [`Reflect`] value. /// /// Returns true if and only if all of the following are true: diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 4e96d50f20351..bc3438f32ef6c 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -391,6 +391,33 @@ impl Reflect for DynamicTuple { impl_type_path!((in bevy_reflect) DynamicTuple); +impl FromIterator> for DynamicTuple { + fn from_iter>>(fields: I) -> Self { + Self { + represented_type: None, + fields: fields.into_iter().collect(), + } + } +} + +impl IntoIterator for DynamicTuple { + type Item = Box; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.fields.into_iter() + } +} + +impl<'a> IntoIterator for &'a DynamicTuple { + type Item = &'a dyn Reflect; + type IntoIter = TupleFieldIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_fields() + } +} + /// Applies the elements of `b` to the corresponding elements of `a`. /// /// # Panics diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 87c87fb3760de..098d0b682192a 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -426,6 +426,33 @@ impl From for DynamicTupleStruct { } } +impl FromIterator> for DynamicTupleStruct { + fn from_iter>>(fields: I) -> Self { + Self { + represented_type: None, + fields: fields.into_iter().collect(), + } + } +} + +impl IntoIterator for DynamicTupleStruct { + type Item = Box; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.fields.into_iter() + } +} + +impl<'a> IntoIterator for &'a DynamicTupleStruct { + type Item = &'a dyn Reflect; + type IntoIter = TupleStructFieldIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_fields() + } +} + /// Compares a [`TupleStruct`] with a [`Reflect`] value. /// /// Returns true if and only if all of the following are true: diff --git a/examples/reflection/dynamic_types.rs b/examples/reflection/dynamic_types.rs index cdf9112745896..420481e8df2f6 100644 --- a/examples/reflection/dynamic_types.rs +++ b/examples/reflection/dynamic_types.rs @@ -135,10 +135,7 @@ fn main() { // Lastly, while dynamic types are commonly generated via reflection methods like // `Reflect::clone_value` or via the reflection deserializers, // you can also construct them manually. - let mut my_dynamic_list = DynamicList::default(); - my_dynamic_list.push(1u32); - my_dynamic_list.push(2u32); - my_dynamic_list.push(3u32); + let mut my_dynamic_list = DynamicList::from_iter([1u32, 2u32, 3u32]); // This is useful when you just need to apply some subset of changes to a type. let mut my_list: Vec = Vec::new(); @@ -167,7 +164,7 @@ fn main() { // 2. `DynamicArray` { - let dynamic_array = DynamicArray::from_vec(vec![1u32, 2u32, 3u32]); + let dynamic_array = DynamicArray::from_iter([1u32, 2u32, 3u32]); let mut my_array = [0u32; 3]; my_array.apply(&dynamic_array); @@ -176,10 +173,7 @@ fn main() { // 3. `DynamicList` { - let mut dynamic_list = DynamicList::default(); - dynamic_list.push(1u32); - dynamic_list.push(2u32); - dynamic_list.push(3u32); + let dynamic_list = DynamicList::from_iter([1u32, 2u32, 3u32]); let mut my_list: Vec = Vec::new(); my_list.apply(&dynamic_list); @@ -188,10 +182,7 @@ fn main() { // 4. `DynamicMap` { - let mut dynamic_map = DynamicMap::default(); - dynamic_map.insert("x", 1u32); - dynamic_map.insert("y", 2u32); - dynamic_map.insert("z", 3u32); + let dynamic_map = DynamicMap::from_iter([("x", 1u32), ("y", 2u32), ("z", 3u32)]); let mut my_map: HashMap<&str, u32> = HashMap::new(); my_map.apply(&dynamic_map);