Skip to content

Commit

Permalink
bevy_reflect: IntoIter for DynamicList and DynamicMap (bevyengi…
Browse files Browse the repository at this point in the history
…ne#4108)

# Objective

In some cases, you may want to take ownership of the values in `DynamicList` or `DynamicMap`. 

I came across this need while trying to implement a custom deserializer, but couldn't get ownership of the values in the list.

## Solution

Implemented `IntoIter` for both `DynamicList` and `DynamicMap`.
  • Loading branch information
MrGVSV authored and exjam committed May 22, 2022
1 parent 67fb0df commit e9f2e82
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
27 changes: 27 additions & 0 deletions crates/bevy_reflect/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ impl<'a> Iterator for ListIter<'a> {
}
}

impl IntoIterator for DynamicList {
type Item = Box<dyn Reflect>;
type IntoIter = std::vec::IntoIter<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.values.into_iter()
}
}

impl<'a> ExactSizeIterator for ListIter<'a> {}

/// Applies the elements of `b` to the corresponding elements of `a`.
Expand Down Expand Up @@ -244,3 +253,21 @@ pub fn list_partial_eq<L: List>(a: &L, b: &dyn Reflect) -> Option<bool> {

Some(true)
}

#[cfg(test)]
mod tests {
use super::DynamicList;

#[test]
fn test_into_iter() {
let mut list = DynamicList::default();
list.push(0usize);
list.push(1usize);
list.push(2usize);
let items = list.into_iter();
for (index, item) in items.into_iter().enumerate() {
let value = item.take::<usize>().expect("couldn't downcast to usize");
assert_eq!(index, value);
}
}
}
34 changes: 34 additions & 0 deletions crates/bevy_reflect/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ impl<'a> Iterator for MapIter<'a> {
}
}

impl IntoIterator for DynamicMap {
type Item = (Box<dyn Reflect>, Box<dyn Reflect>);
type IntoIter = std::vec::IntoIter<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.values.into_iter()
}
}

impl<'a> ExactSizeIterator for MapIter<'a> {}

/// Compares a [`Map`] with a [`Reflect`] value.
Expand Down Expand Up @@ -253,3 +262,28 @@ pub fn map_partial_eq<M: Map>(a: &M, b: &dyn Reflect) -> Option<bool> {

Some(true)
}

#[cfg(test)]
mod tests {
use super::DynamicMap;

#[test]
fn test_into_iter() {
let expected = vec!["foo", "bar", "baz"];

let mut map = DynamicMap::default();
map.insert(0usize, expected[0].to_string());
map.insert(1usize, expected[1].to_string());
map.insert(2usize, expected[2].to_string());

for (index, item) in map.into_iter().enumerate() {
let key = item.0.take::<usize>().expect("couldn't downcast to usize");
let value = item
.1
.take::<String>()
.expect("couldn't downcast to String");
assert_eq!(index, key);
assert_eq!(expected[index], value);
}
}
}

0 comments on commit e9f2e82

Please sign in to comment.