I am writing a container implementing the prefix tree in a generic way (key and value are generic parameters). Due to the nature of this data structure I need the key to have an iterator.
Essentially in accordance to this question the IntoIterator trait is responsible for this possibility but not all the structures implement it. For example &str and String do not implement it.
What should I do in this case when IntoIterator isn't implemented by the standard type?
An expected API is
let mut t1 = Trie::new();
t1.insert(String::from("this"), 1);
let mut t2 = Trie::new();
t2.insert(vec![1, 2, 3], 1);
The problem with String and str is that they have two types of iterators - chars() - iterator over UTF-8 chars and bytes() - iterator over bytes. That's why it's impossible to implement IntoIterator for these types. You have to create two wrappers (or pick one of them)
struct ByteString(String)
struct Utf8String(String)
and implement IntoIterator for them.
The easiest solution, as stated in the comments, is to create a wrapper type:
use ::std::iter::IntoIterator;
struct StringWrapper<'a>(&'a str);
impl<'a> IntoIterator for StringWrapper<'a> {
type Item = char;
type IntoIter = ::std::str::Chars<'a>;
fn into_iter(self) -> Self::IntoIter {
self.0.chars()
}
}
fn main() {
// Raw str
let wr = StringWrapper("test 1");
for c in wr {
println!("{}", c);
}
println!("-----");
// Reference to raw str
let s = "test 2";
let wr_s = StringWrapper(s);
for c in wr_s {
println!("{}", c);
}
println!("-----");
// reference to String
let owned_s = "test 3";
let wr_s_owned = StringWrapper(&owned_s);
for c in wr_s_owned {
println!("{}", c);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With