I am defining a Trait where different implementations for different Structs can return different types of Iterator.
For the Trait I'm using Associated Types:
// Some types for simplicity
pub type ConsData<T> = Box<dyn Iterator<Item = Tuple<T>>>;
pub type VecOfTuples<T> = Vec<Tuple<T>>;
// My Trait...
pub trait Operation<T> {
type Iter: Iterator<Item = Tuple<T>> + ExactSizeIterator;
fn count(&mut self) -> usize;
fn eval(&mut self) -> Self::Iter;
fn collect(&mut self) -> VecOfTuples<T> {
self.eval().collect()
}
fn first(&mut self) -> VecOfTuples<T> {
let mut result: VecOfTuples<T> = Vec::with_capacity(1);
if let Some(tuple) = self.eval().next() {
result.push(tuple);
}
result
}
}
I've implemented the Trait succesfully for the type ConsData
:
impl<T> Operation<T> for ConsData<T>
where
Self: ExactSizeIterator<Item = Tuple<T>> + Copy,
{
type Iter = Self;
fn eval(&mut self) -> Self::Iter {
*self
}
fn count(&mut self) -> usize {
self.len()
}
}
So I could do:
let vector: VecOfTuples<usize> = vec![Tuple::new(1), Tuple::new(2)];
let cons: ConsData<usize> = Box::new(vector.into_iter());
let a: VecOfTuples<usize> = cons.collect();
println!("{:?}", a); // Expected [Tuple(1), Tuple(2)]
But now, when I try to implement the same Trait for a struct called MapOperation
which returns a Map
Iterator It throws that method collect()
is not implemented. Here's my impl
for MapOperation
:
pub struct MapOperation<O, U, T> {
data: O,
map_function: fn(Tuple<U>) -> Tuple<T>,
}
impl<O, T, U> Operation<T> for MapOperation<O, U, T>
where
O: Operation<U>,
{
type Iter = Map<<O>::Iter, fn(Tuple<U>) -> Tuple<T>>;
fn eval(&mut self) -> Self::Iter {
self.data.eval().map(self.map_function)
}
fn count(&mut self) -> usize {
self.data.count()
}
}
The definition compiles without errors. But then, when I try to run this:
Fails saying that my MapOperation does not implement the trait Operation.
let a_map_funcion: fn(Tuple<usize>) -> Tuple<(usize, usize, bool)> =
|tuple| Tuple::new((tuple.0, 4, true));
let operation = MapOperation {
data: cons,
map_function: a_map_funcion,
};
let result: VecOfTuples<(usize, usize, bool)> = operation.collect();
Here there is a playground to try the code.
Why It's not working? As I see there is an explicit impl
for the MapOperation
struct, which contains a ConsData
in the data
field, which implements Operation
too. I'd need a solution that works with any kind of Iterator, here is a constant Vec and Map, but It could be a Filter, FilterMap, etc.
Thanks in advance and sorry about my English