Hi,
I've got a problem using chain()
method with flat_map()
. Here is a working Elixir prototype (you may skip it for now):
def traverse_flat_dst(src_dir, dst_root, dst_step \\ []) do
{dirs, files} = list_dir_groom(src_dir) # Getting immediate offspring.
traverse = fn d ->
step = dst_step ++ [Path.basename(d)]
traverse_flat_dst(d, dst_root, step)
end
handle = fn f ->
dst_path =
Path.join(
dst_root,
dst_step
)
{f, dst_path}
end
Stream.flat_map(dirs, traverse)
|> Stream.concat(Stream.map(files, handle))
end
This is s stripped down Rust version:
fn traverse_flat_dst_iter(
src_dir: &PathBuf,
) -> impl Iterator<Item = (PathBuf, PathBuf)> {
let (dirs, files) = list_dir_groom(src_dir);
let traverse = |d: &PathBuf| {
traverse_flat_dst_iter(d)
};
//// Three commented out lines below are good and working Rust, they just do nothing useful.
// dirs.into_iter()
// .map(|d| (d, PathBuf::new()))
// .chain(files.into_iter().map(|f| (f, PathBuf::new())))
dirs.into_iter()
.flat_map(traverse)
.chain(files.into_iter().map(|f| (f, PathBuf::new())))
}
The flat_map()
thing won't compile:
rror[E0631]: type mismatch in closure arguments
--> src/main.rs:275:10
|
267 | let traverse = |d: &PathBuf| {
| ------------- found signature of `for<'r> fn(&'r std::path::PathBuf) -> _`
...
275 | .flat_map(traverse)
| ^^^^^^^^ expected signature of `fn(std::path::PathBuf) -> _`
error[E0599]: no method named `chain` found for type `std::iter::FlatMap<std::vec::IntoIter<std::path::PathBuf>, _, [closure@src/main.rs:267:20: 269:6]>` in the current scope
--> src/main.rs:276:10
|
276 | .chain(files.into_iter().map(|f| (f, PathBuf::new())))
| ^^^^^
|
= note: the method `chain` exists but the following trait bounds were not satisfied:
`&mut std::iter::FlatMap<std::vec::IntoIter<std::path::PathBuf>, _, [closure@src/main.rs:267:20: 269:6]> : std::iter::Iterator`
`std::iter::FlatMap<std::vec::IntoIter<std::path::PathBuf>, _, [closure@src/main.rs:267:20: 269:6]> : std::iter::Iterator`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0599`.
I hope, Rust type annotations explain the idea: a recursive function, which is walking a file tree, returns an iterator serving (PathBuf, PathBuf)
tuple. The iterator serves all the files of the tree. With the commented out stub it even kind of works.
What am I still missing?