Skip to content

Instantly share code, notes, and snippets.

@aboglioli
Last active May 3, 2020 07:50
Show Gist options
  • Save aboglioli/5f70326e73281c704f89182429657588 to your computer and use it in GitHub Desktop.
Save aboglioli/5f70326e73281c704f89182429657588 to your computer and use it in GitHub Desktop.
Iterator as function argument, implemented with genercis and trait object.
use std::collections::HashMap;
use std::iter::Iterator;
// Data
#[derive(Debug)]
struct Common(i32);
#[derive(Debug)]
struct Data<'a> {
id: i32,
value: String,
common: &'a Common,
}
impl<'a> Data<'a> {
fn new(id: i32, value: String, common: &Common) -> Data {
Data { id, value, common }
}
}
// Dynamic handlers
trait Handler {
fn proc<'a>(&self, data: Box<dyn Iterator<Item = &mut Data> + 'a>);
}
struct Multiplier(i32);
impl Handler for Multiplier {
fn proc<'a>(&self, data: Box<dyn Iterator<Item = &mut Data> + 'a>) {
for d in data {
d.id = d.id * self.0;
}
}
}
struct Adder(i32);
impl Handler for Adder {
fn proc<'a>(&self, data: Box<dyn Iterator<Item = &mut Data> + 'a>) {
for d in data {
d.id = d.id + self.0;
}
}
}
// Statis handlers
trait SHandler {
fn proc<'a, 'b: 'a, I>(&self, data: I)
where
I: Iterator<Item = &'a mut Data<'b>>;
}
struct SMultiplier(i32);
impl SHandler for SMultiplier {
fn proc<'a, 'b: 'a, I>(&self, data: I)
where
I: Iterator<Item = &'a mut Data<'b>>,
{
for d in data {
d.id = d.id * self.0;
}
}
}
struct SAdder(i32);
impl SHandler for SAdder {
fn proc<'a, 'b: 'a, I>(&self, data: I)
where
I: Iterator<Item = &'a mut Data<'b>>,
{
for d in data {
d.id = d.id + self.0;
}
}
}
// Iterators
fn iterate<'a, 'b: 'a, T>(vec: T)
where
T: Iterator<Item = &'a mut Data<'b>>,
{
for d in vec {
d.id = d.id * 2;
}
}
fn iterate_dyn<'a>(vec: Box<dyn Iterator<Item = &mut Data> + 'a>) {
for d in vec {
d.id = d.id * 2;
}
}
fn iterate_impl<'a, 'b: 'a>(vec: impl Iterator<Item = &'a mut Data<'b>>) {
for d in vec {
d.id = d.id * 2;
}
}
fn main() {
let common = Common(32);
let d1 = Data::new(1, "Hello".to_string(), &common);
let d2 = Data::new(2, "Bye".to_string(), &common);
let mut map = HashMap::new();
map.insert(1, d1);
map.insert(2, d2);
iterate(map.values_mut());
iterate_dyn(Box::new(map.values_mut()));
iterate_impl(Box::new(map.values_mut()));
println!("{:?}", map);
// Dynamic handlers
let handlers: Vec<Box<dyn Handler>> = vec![Box::new(Multiplier(3)), Box::new(Adder(4))];
for h in handlers.iter() {
h.proc(Box::new(map.values_mut()));
}
println!("{:?}", map);
// Static handlers
let handlers = vec![Box::new(SMultiplier(3)), Box::new(SMultiplier(4))]; // Cannot use SAdd because Vec<T> must only save same structs
for h in handlers.iter() {
h.proc(Box::new(map.values_mut()));
}
println!("{:?}", map);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment