I have a trait which is something like Iterator, and a wrapper around it:
pub struct Wrapped<I: Iterator>(I);
Many of the functions on wrapped iterators return new wrapped iterators using impl-trait.
impl <I: Iterator> Wrapped<I> {
pub fn foo(self) -> Wrapped<impl Iterator<Item=Foo<I::Item>>> {...}
pub fn bar(self) -> Wrapped<impl Iterator<Item=Bar<I::Item>>> {...}
}
so that after a while, it becomes easy for the user to lose track of what the iterator item is in the calling code (eg. for expressions like my_wrapped.foo().bar().bar().foo()).
I'd like to give the user a way to explicitly specify what type they expect the Item to be such that if it's not that type then there's a compile-time error:
let y = x.foo().bar().bar().foo().assert_item_type::<Foo<Bar<Bar<Foo<X>>>>>()
but so far, the only way I've found to do this is a bit weird and ugly. Is there a cleaner way?
pub trait Is {
type Myself;
}
impl<T> Is for T {
type Myself = T;
}
impl <I: Iterator> Wrapped<I> {
pub fn assert_item_type<Item: Is<Myself = I::Item>>(self) -> Self {
self
}
}