Crates.io | dyn-iter |
lib.rs | dyn-iter |
version | 1.0.1 |
source | src |
created_at | 2020-09-22 14:01:34.497362 |
updated_at | 2023-05-23 09:21:09.460608 |
description | Wrapper around `Box |
homepage | https://gitlab.com/woshilapin/dyn-iter.git |
repository | https://gitlab.com/woshilapin/dyn-iter.git |
max_upload_size | |
id | 291556 |
size | 16,352 |
dyn-iter
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.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Color {
Red,
Green,
Blue,
White,
Black,
}
trait Colors<'a> {
type ColorsIter: Iterator<Item = Color> + 'a;
fn colors(&'a self) -> Self::ColorsIter;
}
As an implementor, you have a struct Flag
that looks like this.
# use std::collections::HashSet;
# #[derive(Debug, Clone, Copy, PartialEq, Eq)]
# enum Color {
# Red,
# Green,
# Blue,
# White,
# Black,
# }
struct Flag {
pub primary_colors: HashSet<Color>,
pub secondary_colors: HashSet<Color>,
}
you might implement Colors
that look like this
# 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<Color>,
# pub secondary_colors: HashSet<Color>,
# }
# trait Colors<'a> {
# type ColorsIter: Iterator<Item = Color> + '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.
# 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<Color>,
# pub secondary_colors: HashSet<Color>,
# }
# trait Colors<'a> {
# type ColorsIter: Iterator<Item = Color> + '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<dyn Iterator<Item = V> + 'iter>
.
For more details about why this crate exists, read this blog post.