Implement FromIterator/IntoIterator for dynamic types (#14250)
# Objective Implement FromIterator/IntoIterator for dynamic types where missing Note: - can't impl `IntoIterator` for `&Array` & co because of orphan rules - `into_iter().collect()` is a no-op for `Vec`s because of specialization --- ## Migration Guide - Change `DynamicArray::from_vec` to `DynamicArray::from_iter`
This commit is contained in:
parent
18abe2186c
commit
ab255aefc6
@ -203,15 +203,9 @@ impl DynamicArray {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.15.0", note = "use from_iter")]
|
||||
pub fn from_vec<T: Reflect>(values: Vec<T>) -> Self {
|
||||
Self {
|
||||
represented_type: None,
|
||||
values: values
|
||||
.into_iter()
|
||||
.map(|field| Box::new(field) as Box<dyn Reflect>)
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice(),
|
||||
}
|
||||
Self::from_iter(values)
|
||||
}
|
||||
|
||||
/// Sets the [type] to be represented by this `DynamicArray`.
|
||||
@ -369,6 +363,42 @@ impl Array for DynamicArray {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Box<dyn Reflect>> for DynamicArray {
|
||||
fn from_iter<I: IntoIterator<Item = Box<dyn Reflect>>>(values: I) -> Self {
|
||||
Self {
|
||||
represented_type: None,
|
||||
values: values.into_iter().collect::<Vec<_>>().into_boxed_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflect> FromIterator<T> for DynamicArray {
|
||||
fn from_iter<I: IntoIterator<Item = T>>(values: I) -> Self {
|
||||
values
|
||||
.into_iter()
|
||||
.map(|value| Box::new(value).into_reflect())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DynamicArray {
|
||||
type Item = Box<dyn Reflect>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
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);
|
||||
#[cfg(feature = "functions")]
|
||||
crate::func::macros::impl_function_traits!(DynamicArray);
|
||||
|
@ -1092,7 +1092,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);
|
||||
|
@ -388,6 +388,24 @@ impl Debug for DynamicList {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Box<dyn Reflect>> for DynamicList {
|
||||
fn from_iter<I: IntoIterator<Item = Box<dyn Reflect>>>(values: I) -> Self {
|
||||
Self {
|
||||
represented_type: None,
|
||||
values: values.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflect> FromIterator<T> for DynamicList {
|
||||
fn from_iter<I: IntoIterator<Item = T>>(values: I) -> Self {
|
||||
values
|
||||
.into_iter()
|
||||
.map(|field| Box::new(field).into_reflect())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DynamicList {
|
||||
type Item = Box<dyn Reflect>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
@ -397,6 +415,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,
|
||||
|
@ -478,6 +478,26 @@ impl<'a> Iterator for MapIter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<(Box<dyn Reflect>, Box<dyn Reflect>)> for DynamicMap {
|
||||
fn from_iter<I: IntoIterator<Item = (Box<dyn Reflect>, Box<dyn Reflect>)>>(items: I) -> Self {
|
||||
let mut map = Self::default();
|
||||
for (key, value) in items.into_iter() {
|
||||
map.insert_boxed(key, value);
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Reflect, V: Reflect> FromIterator<(K, V)> for DynamicMap {
|
||||
fn from_iter<I: IntoIterator<Item = (K, V)>>(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<dyn Reflect>, Box<dyn Reflect>);
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
@ -487,6 +507,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.
|
||||
|
@ -508,6 +508,39 @@ impl Debug for DynamicStruct {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N> FromIterator<(N, Box<dyn Reflect>)> for DynamicStruct
|
||||
where
|
||||
N: Into<Cow<'a, str>>,
|
||||
{
|
||||
/// Create a dynamic struct that doesn't represent a type from the
|
||||
/// field name, field value pairs.
|
||||
fn from_iter<I: IntoIterator<Item = (N, Box<dyn Reflect>)>>(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<dyn Reflect>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
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:
|
||||
|
@ -391,6 +391,33 @@ impl Reflect for DynamicTuple {
|
||||
|
||||
impl_type_path!((in bevy_reflect) DynamicTuple);
|
||||
|
||||
impl FromIterator<Box<dyn Reflect>> for DynamicTuple {
|
||||
fn from_iter<I: IntoIterator<Item = Box<dyn Reflect>>>(fields: I) -> Self {
|
||||
Self {
|
||||
represented_type: None,
|
||||
fields: fields.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DynamicTuple {
|
||||
type Item = Box<dyn Reflect>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
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
|
||||
|
@ -426,6 +426,33 @@ impl From<DynamicTuple> for DynamicTupleStruct {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Box<dyn Reflect>> for DynamicTupleStruct {
|
||||
fn from_iter<I: IntoIterator<Item = Box<dyn Reflect>>>(fields: I) -> Self {
|
||||
Self {
|
||||
represented_type: None,
|
||||
fields: fields.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DynamicTupleStruct {
|
||||
type Item = Box<dyn Reflect>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
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:
|
||||
|
@ -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<u32> = 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<u32> = 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);
|
||||
|
Loading…
Reference in New Issue
Block a user