From 422695a4597ed656b7f1e18d447f5880e5f7a6a3 Mon Sep 17 00:00:00 2001
From: Alejandro Perea <alexpro820@gmail.com>
Date: Tue, 8 Mar 2022 16:23:36 +0100
Subject: [PATCH] Add `Tileset::iter`, remove Iterator types (#189)

* Implement `Tileset::tiles`

* Remove iterator types

* Small fixes

* Remove unused lifetime
---
 src/layers/group.rs  | 41 +++++------------------------------------
 src/layers/object.rs | 44 +++++---------------------------------------
 src/map.rs           | 33 ++-------------------------------
 src/tileset.rs       |  8 ++++++++
 4 files changed, 20 insertions(+), 106 deletions(-)

diff --git a/src/layers/group.rs b/src/layers/group.rs
index 55cd93f..b0f9ede 100644
--- a/src/layers/group.rs
+++ b/src/layers/group.rs
@@ -7,7 +7,7 @@ use crate::{
     map::MapTilesetGid,
     properties::{parse_properties, Properties},
     util::*,
-    Error, Layer, Map,
+    Error, Layer,
 };
 
 /// The raw data of a [`GroupLayer`]. Does not include a reference to its parent [`Map`](crate::Map).
@@ -90,8 +90,10 @@ map_wrapper!(
 
 impl<'map> GroupLayer<'map> {
     /// Returns an iterator over the layers present in this group in display order.
-    pub fn layers(&self) -> GroupLayerIter {
-        GroupLayerIter::new(self.map, self.data)
+    pub fn layers(&self) -> impl ExactSizeIterator<Item = Layer> {
+        self.layers
+            .iter()
+            .map(move |layer| Layer::new(self.map, layer))
     }
     /// Gets a specific layer from the group by index.
     pub fn get_layer(&self, index: usize) -> Option<Layer> {
@@ -101,36 +103,3 @@ impl<'map> GroupLayer<'map> {
             .map(|data| Layer::new(self.map, data))
     }
 }
-
-/// An iterator that iterates over all the layers in a group layer, obtained via [`GroupLayer::layers`].
-#[derive(Debug)]
-pub struct GroupLayerIter<'map> {
-    map: &'map Map,
-    group: &'map GroupLayerData,
-    index: usize,
-}
-
-impl<'map> GroupLayerIter<'map> {
-    fn new(map: &'map Map, group: &'map GroupLayerData) -> Self {
-        Self {
-            map,
-            group,
-            index: 0,
-        }
-    }
-}
-
-impl<'map> Iterator for GroupLayerIter<'map> {
-    type Item = Layer<'map>;
-    fn next(&mut self) -> Option<Self::Item> {
-        let layer_data = self.group.layers.get(self.index)?;
-        self.index += 1;
-        Some(Layer::new(self.map, layer_data))
-    }
-}
-
-impl<'map> ExactSizeIterator for GroupLayerIter<'map> {
-    fn len(&self) -> usize {
-        self.group.layers.len() - self.index
-    }
-}
diff --git a/src/layers/object.rs b/src/layers/object.rs
index f2c9f4d..55aca66 100644
--- a/src/layers/object.rs
+++ b/src/layers/object.rs
@@ -5,7 +5,7 @@ use xml::attribute::OwnedAttribute;
 use crate::{
     parse_properties,
     util::{get_attrs, map_wrapper, parse_tag, XmlEventResult},
-    Color, Error, Map, MapTilesetGid, Object, ObjectData, Properties, Result,
+    Color, Error, MapTilesetGid, Object, ObjectData, Properties, Result,
 };
 
 /// Raw data referring to a map object layer or tile collision data.
@@ -69,43 +69,9 @@ impl<'map> ObjectLayer<'map> {
     /// Returns an iterator over the objects present in this layer, in the order they were declared
     /// in in the TMX file.
     #[inline]
-    pub fn objects(&self) -> Objects<'map> {
-        Objects::new(self.map, self.data)
-    }
-}
-
-/// An iterator that iterates over all the objects in an object layer, obtained via [`ObjectLayer::objects`].
-#[derive(Debug)]
-pub struct Objects<'map> {
-    map: &'map Map,
-    data: &'map ObjectLayerData,
-    index: usize,
-}
-
-impl<'map> Objects<'map> {
-    #[inline]
-    fn new(map: &'map Map, data: &'map ObjectLayerData) -> Self {
-        Self {
-            map,
-            data,
-            index: 0,
-        }
-    }
-}
-
-impl<'map> Iterator for Objects<'map> {
-    type Item = Object<'map>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let object_data = self.data.objects.get(self.index)?;
-        self.index += 1;
-        Some(Object::new(self.map, object_data))
-    }
-}
-
-impl<'map> ExactSizeIterator for Objects<'map> {
-    #[inline]
-    fn len(&self) -> usize {
-        self.data.objects.len() - self.index
+    pub fn objects(&self) -> impl ExactSizeIterator<Item = Object> {
+        self.objects
+            .iter()
+            .map(move |object| Object::new(self.map, object))
     }
 }
diff --git a/src/map.rs b/src/map.rs
index e75fd14..4890f53 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -135,8 +135,8 @@ impl Map {
 
     /// Get an iterator over all the layers in the map in ascending order of their layer index.
     #[inline]
-    pub fn layers(&self) -> MapLayerIter {
-        MapLayerIter::new(self)
+    pub fn layers(&self) -> impl ExactSizeIterator<Item = Layer> {
+        self.layers.iter().map(move |layer| Layer::new(self, layer))
     }
 
     /// Returns the layer that has the specified index, if it exists.
@@ -145,35 +145,6 @@ impl Map {
     }
 }
 
-/// An iterator that iterates over all the layers in a map, obtained via [`Map::layers`].
-#[derive(Debug)]
-pub struct MapLayerIter<'map> {
-    map: &'map Map,
-    index: usize,
-}
-
-impl<'map> MapLayerIter<'map> {
-    fn new(map: &'map Map) -> Self {
-        Self { map, index: 0 }
-    }
-}
-
-impl<'map> Iterator for MapLayerIter<'map> {
-    type Item = Layer<'map>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let layer_data = self.map.layers.get(self.index)?;
-        self.index += 1;
-        Some(Layer::new(self.map, layer_data))
-    }
-}
-
-impl<'map> ExactSizeIterator for MapLayerIter<'map> {
-    fn len(&self) -> usize {
-        self.map.layers.len() - self.index
-    }
-}
-
 impl Map {
     fn parse_xml(
         parser: &mut impl Iterator<Item = XmlEventResult>,
diff --git a/src/tileset.rs b/src/tileset.rs
index c88a0bd..5cdeeaf 100644
--- a/src/tileset.rs
+++ b/src/tileset.rs
@@ -127,6 +127,14 @@ impl Tileset {
     pub fn get_tile(&self, id: u32) -> Option<Tile> {
         self.tiles.get(&id).map(|data| Tile::new(self, data))
     }
+
+    /// Iterates through the tiles from this tileset.
+    #[inline]
+    pub fn tiles(&self) -> impl ExactSizeIterator<Item = (u32, Tile)> {
+        self.tiles
+            .iter()
+            .map(move |(id, data)| (*id, Tile::new(self, data)))
+    }
 }
 
 impl Tileset {
-- 
GitLab