dyn-iter

![continuous-integration-badge] ![code-coverage-badge] ![crates.io-badge] ![license-badge] ![documentation-badge]

This tiny crate should help you simplify your code when you need to wrap [Iterator] as trait-object.

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 primarycolors: HashSet, pub secondarycolors: 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.primarycolors .iter() .chain(&self.secondarycolors) .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.primarycolors .iter() .chain(&self.secondarycolors) .filter(|color| **color != Color::Black) .copied() .intodyniter() } } ```

Behind the scene, DynIter<'iter, V> is only providing a wrapper around a Box<dyn Iterator<Item = V> + 'iter>.

For more details about why this crate exists, read this [blog post].