# `dyn-iter` [![continuous-integration-badge]][continuous-integration] [![code-coverage-badge]][code-coverage] [![crates.io-badge]][crates.io] [![license-badge]][license] [![documentation-badge]][documentation] [continuous-integration-badge]: https://img.shields.io/gitlab/pipeline-status/woshilapin/dyn-iter.svg?branch=main&color=fca121&logo=gitlab&style=flat [continuous-integration]: https://gitlab.com/woshilapin/dyn-iter/-/pipelines/main/latest [code-coverage-badge]: https://img.shields.io/codecov/c/gitlab/woshilapin/dyn-iter?style=flat&logo=codecov&color=f01f7a [code-coverage]: https://codecov.io/gl/woshilapin/dyn-iter [crates.io-badge]: https://img.shields.io/crates/v/dyn-iter?style=flat&logo=data:image/png;base64,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&color=e6ac38 [crates.io]: https://crates.io/crates/dyn-iter [license-badge]: https://img.shields.io/crates/l/dyn-iter?style=flat&logo=spdx&color=4398cc [license]: https://spdx.org/licenses/MIT.html [documentation-badge]: https://img.shields.io/badge/docs.rs-dyn--iter-4d76ae?style=flat&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K&color=4d76ae [documentation]: https://docs.rs/dyn-iter/latest/dyn_iter/ This tiny crate should help you simplify your code when you need to wrap [`Iterator`] as trait-object. [`iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html Imagine for example a trait like the following. ```rust #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Color { Red, Green, Blue, White, Black, } trait Colors<'a> { type ColorsIter: Iterator + 'a; fn colors(&'a self) -> Self::ColorsIter; } ``` As an implementor, you have a `struct Flag` that looks like this. ```rust # use std::collections::HashSet; # #[derive(Debug, Clone, Copy, PartialEq, Eq)] # enum Color { # Red, # Green, # Blue, # White, # Black, # } struct Flag { pub primary_colors: HashSet, pub secondary_colors: HashSet, } ``` you might implement `Colors` that look like this ```rust,ignore # use std::collections::HashSet; # use dyn_iter::{DynIter, IntoDynIterator as _}; # #[derive(Debug, Clone, Copy, PartialEq, Eq)] # enum Color { # Red, # Green, # Blue, # White, # Black, # } # struct Flag { # pub primary_colors: HashSet, # pub secondary_colors: HashSet, # } # trait Colors<'a> { # type ColorsIter: Iterator + 'a; # fn colors(&'a self) -> Self::ColorsIter; # } impl<'a> Colors<'a> for Flag { type ColorsIter = ???; fn colors(&'a self) -> Self::ColorsIter { self.primary_colors .iter() .chain(&self.secondary_colors) .filter(|color| **color != Color::Black) .copied() } } ``` With the above implementation, defining the associated type `ColorsIter` might be difficult. `DynIter` should simplify your life because you can just write the following implementation. ```rust # use std::collections::HashSet; # use dyn_iter::{DynIter, IntoDynIterator as _}; # #[derive(Debug, Clone, Copy, PartialEq, Eq)] # enum Color { # Red, # Green, # Blue, # White, # Black, # } # struct Flag { # pub primary_colors: HashSet, # pub secondary_colors: HashSet, # } # trait Colors<'a> { # type ColorsIter: Iterator + 'a; # fn colors(&'a self) -> Self::ColorsIter; # } impl<'a> Colors<'a> for Flag { type ColorsIter = DynIter<'a, Color>; fn colors(&'a self) -> Self::ColorsIter { self.primary_colors .iter() .chain(&self.secondary_colors) .filter(|color| **color != Color::Black) .copied() .into_dyn_iter() } } ``` Behind the scene, `DynIter<'iter, V>` is only providing a wrapper around a `Box + 'iter>`. For more details about why this crate exists, read this [blog post]. [blog post]: https://hole.tuziwo.info/dyn-iterator.html