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