Reputation: 1316
Consider these two traits:
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
and
trait SeeekingIterator {
type Item;
fn next(&mut self, other: &Self::Item) -> Option<Self::Item>;
}
Now assume, I wanted to implement something like std::iter::Peekable
for structs that implement both Iterator
and SeekingIterator
.
This would look a bit like:
struct PeekableSeekable<I> where
I: Iterator + SeekingIterator
{
iter: I,
peeked: Option<<I as Iterator>::Item>
}
It would implement
fn peek(&mut self) -> Option<&<I as Iterator>::Item>;
and
fn peek_seek(&mut self, other: &<I as SeekingIterator>::Item) -> Option<&<I as SeekingIterator>::Item>
The problem now is, that this would only work if <I as Iterator>::Item == <I as SeekingIterator>::Item
.
I don't know of a way to express this inside a where
clause.
I'm faking it by using
Option<<I as Iterator>::Item>: From<Option<<I as SeekingIterator>::Item>>
and
Option<<I as SeekingIterator>::Item>: From<Option<<I as Iterator>::Item>>
And then calling Option::from
when a transformation is needed. This seems a bit ugly and I am wondering if this problem could be solved more concisely.
Upvotes: 2
Views: 936
Reputation: 432139
Reference one trait from the other trait constraint:
struct PeekableSeekable<I>
where I: Iterator
{
iter: I,
peeked: Option<I::Item>,
}
impl<I> PeekableSeekable<I>
where I: Iterator<Item = <I as SeekingIterator>::Item> + SeekingIterator
{
// Implement
}
Upvotes: 6