I'm trying to iterate depth-first over a tree structure in Rust. I thought I had a really nice concise solution for this, but I can't get it to compile. Conceptually it's pretty simple: iterate over the children, get each child's depth first iterator, flatten them, and chain the current node's metadata iterator to it.
#[derive(Debug, Eq, PartialEq)]
struct Node {
metadata: Vec<i64>,
children: Vec<Box<Node>>,
}
impl Node {
fn depth_first_metadata_iter(&self) -> impl Iterator<Item = &i64> + '_ {
self.children
.iter()
.map(|child| child.depth_first_metadata_iter())
.flatten()
.chain(self.metadata.iter())
}
}
fn main() {
let tree = Node {
metadata: vec![1, 2, 3],
children: vec![
Box::new(Node {
metadata: vec![4, 5],
children: vec![],
}),
Box::new(Node {
metadata: vec![6, 7],
children: vec![],
}),
],
};
println!(
"{:?}",
tree.depth_first_metadata_iter().collect::<Vec<&i64>>()
);
}
However, when I compile this, I get the following error:
error[E0275]: overflow evaluating the requirement `impl std::iter::Iterator`
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
(You can check this out yourself on the playground.)
It makes sense that this would be an error, as I am making recursive calls inside depth_first_metadata_iter
which return nested iterators, but it would be really nice if something like this code could work without having to implement a custom iterator.
All other solutions to the E0275
error I have seen (eg. this, this, this) seem to involve strategically placing a type annotation somewhere - is something like that possible here, or am I trying something "impossible"?