Trait with method that returns an iterator

I'm trying to define a Trait that returns a heterogeneous tuple Iterator. Since it is not possible in Rust to define Traits with methods as follows:

pub trait Operation<T> {
    /// Returns an iterator of the data
    fn eval(&self) -> impl Iterator<Item = Tuple<T>>;
    
    // ...
}

I've tried with Associated Types. Here there is a playground:

pub trait Operation<T> {
    type Iter: Iterator<Item = Tuple<T>>;

    /// Returns an iterator of the data
    fn eval(&mut self) -> &mut Self::Iter;

    /// Returns the data
    fn collect(&mut self) -> VecOfTuples<T> {
        self.eval().collect()
    }

    /// Returns the number of elements in the Iterator
    fn count(&mut self) -> usize;
}

// Implementation of the Trait "Operation" for ConsData
impl<T> Operation<T> for ConsData<T>
    where Self: ExactSizeIterator
{
    type Iter = Self;
    
    fn eval(&mut self) -> &mut Self::Iter {
        self
    }

    fn count(&mut self) -> usize {
        self.len()
    }
}

But It's throwing:

expected associated type, found struct Tuple

If I remove the where Self: ExactSizeIterator line it doesn't fail but I can't use the len() method. How could I solve this problem? Any kind of help would be really appreciated.

Thanks in advance

1 Like

This is a sort of "bug" of the constraint solver: it forgets what the type of the iterator is when using Self : ExactSizeIterator.

By using

where
    Self : ExactSizeIterator<Item = Tuple<T>>,

it works, so it looks like you were almost there :wink:

2 Likes

You're the best! Thank you so much!

1 Like