From 00f83941b16e7a175c5c1503be81a648e23d81df Mon Sep 17 00:00:00 2001 From: MrGVSV Date: Tue, 26 Apr 2022 00:17:38 +0000 Subject: [PATCH] bevy_reflect: `IntoIter` for `DynamicList` and `DynamicMap` (#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`. --- crates/bevy_reflect/src/list.rs | 27 ++++++++++++++++++++++++++ crates/bevy_reflect/src/map.rs | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index ce434c8c3701f..8de4038866015 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -191,6 +191,15 @@ impl<'a> Iterator for ListIter<'a> { } } +impl IntoIterator for DynamicList { + type Item = Box; + type IntoIter = std::vec::IntoIter; + + 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`. @@ -244,3 +253,21 @@ pub fn list_partial_eq(a: &L, b: &dyn Reflect) -> Option { 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::().expect("couldn't downcast to usize"); + assert_eq!(index, value); + } + } +} diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 02d1ae37a242f..f67683c1b661a 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -220,6 +220,15 @@ impl<'a> Iterator for MapIter<'a> { } } +impl IntoIterator for DynamicMap { + type Item = (Box, Box); + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.values.into_iter() + } +} + impl<'a> ExactSizeIterator for MapIter<'a> {} /// Compares a [`Map`] with a [`Reflect`] value. @@ -253,3 +262,28 @@ pub fn map_partial_eq(a: &M, b: &dyn Reflect) -> Option { 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::().expect("couldn't downcast to usize"); + let value = item + .1 + .take::() + .expect("couldn't downcast to String"); + assert_eq!(index, key); + assert_eq!(expected[index], value); + } + } +}