I'm trying to create code that reads data from some source in both directions without code duplication.
use std::iter;
struct Reader {
data: Vec<usize>,
data_rev: Vec<usize>,
data_it: Box<dyn Iterator<Item = usize>>,
data_it_rev: Box<dyn Iterator<Item = usize>>,
}
enum Direction { Forward, Backward }
impl Reader {
fn read(&mut self, n: usize, direction: Direction) {
let (it, adder) = match direction {
Direction::Forward => {
let adder: Box<dyn FnMut(usize) -> ()> = Box::new(|idx| self.data.push(idx));
(&self.data_it, adder)
}
Direction::Backward => {
let adder: Box<dyn FnMut(usize) -> ()> = Box::new(|idx| self.data_rev.insert(0, idx));
(&self.data_it_rev, adder)
}
};
for idx in it.by_ref().take(n) {
adder(idx);
}
}
}
Full code is here
What I'm trying to represent in this example is read
function that has common code and some code that varies with the direction in which read
should happen.
It's obvious how to write this with multiple pattern matches on direction, but I want to do this without repeating myself.
If possible I'd like to make direction some kind of generic parameter and have something like
struct Reader<D: Directon> {
data: Vec<usize>,
data_it: Box<Iterator<Item = usize>>
}
trait Reader<Direction> {
fn read(&mut self)
}
// somewhere in code
let reader = match direction {
Direction::Forward => self.forward_reader;
Direction::Backward => self.backward_reader;
}
reader.read()