I want the ToKeyIter::Item be equal to ToKeyIter::KeyIter::Item as KeyIter should implement Iterator trait. I couldn't do it because with constraint equality in where clause. That's why I decided to use trait Into.
pub trait ToKeyIter {
type Item: Clone + Hash + Eq;
type KeyIter<'b>: Iterator where Self: 'b, <Self::KeyIter<'b> as Iterator>::Item: Into<Self::Item>;
fn key_iter<'a> (&'a self) -> Self::KeyIter<'a>
where <Self::KeyIter<'a> as Iterator>::Item: Into<Self::Item>;
}
The trait itself compiles, but when I try to impl it for str or String, the compiler fails with "overflow evaluating the requirement".
impl ToKeyIter for str {
type Item = char;
type KeyIter<'a> = Chars<'a>;
fn key_iter<'a> (&'a self) -> Chars<'a> {
self.chars()
}
}
impl ToKeyIter for String {
type Item = char;
type KeyIter<'a> = Chars<'a>;
fn key_iter<'a> (&'a self) -> Chars<'a> {
self.chars()
}
}
If you can tell how to write something like this
Key::Item == Key::KeyIter::Item
it will be great. But also I want to know what I should do to have correct impl for str and String with Into trait.
You can specify the Iterate<Item=Self::Item>
to obtain what you want. See the playground for a live version of this:
#![feature(generic_associated_types)]
use std::hash::Hash;
use std::str::Chars;
pub trait ToKeyIter {
type Item: Clone + Hash + Eq;
type KeyIter<'a>: Iterator<Item=Self::Item>
where
Self: 'a;
fn key_iter<'a>(&'a self) -> Self::KeyIter<'a>;
}
impl ToKeyIter for str {
type Item = char;
type KeyIter<'a> = Chars<'a>;
fn key_iter<'a> (&'a self) -> Chars<'a> {
self.chars()
}
}
impl ToKeyIter for String {
type Item = char;
type KeyIter<'a> = Chars<'a>;
fn key_iter<'a> (&'a self) -> Chars<'a> {
self.chars()
}
}