parallel_disk_usage/
tree_builder.rs

1pub mod info;
2
3pub use info::Info;
4
5use super::{data_tree::DataTree, size};
6use rayon::prelude::*;
7
8/// Collection of functions and starting points in order to build a [`DataTree`] with [`From`] or [`Into`].
9#[derive(Debug)]
10pub struct TreeBuilder<Path, Name, Size, GetInfo, JoinPath>
11where
12    Path: Send + Sync,
13    Name: Send + Sync,
14    GetInfo: Fn(&Path) -> Info<Name, Size> + Copy + Send + Sync,
15    JoinPath: Fn(&Path, &Name) -> Path + Copy + Send + Sync,
16    Size: size::Size + Send,
17{
18    /// Path to the root.
19    pub path: Path,
20    /// Name of the root.
21    pub name: Name,
22    /// Function to extract necessary information from `path` (`size` and `children`).
23    pub get_info: GetInfo,
24    /// Function to join parent's `path` with a child's name to make the child's `name`.
25    pub join_path: JoinPath,
26}
27
28impl<Path, Name, Size, GetInfo, JoinPath> From<TreeBuilder<Path, Name, Size, GetInfo, JoinPath>>
29    for DataTree<Name, Size>
30where
31    Path: Send + Sync,
32    Name: Send + Sync,
33    GetInfo: Fn(&Path) -> Info<Name, Size> + Copy + Send + Sync,
34    JoinPath: Fn(&Path, &Name) -> Path + Copy + Send + Sync,
35    Size: size::Size + Send,
36{
37    /// Create a [`DataTree`] from a [`TreeBuilder`].
38    fn from(builder: TreeBuilder<Path, Name, Size, GetInfo, JoinPath>) -> Self {
39        let TreeBuilder {
40            path,
41            name,
42            get_info,
43            join_path,
44        } = builder;
45
46        let Info { size, children } = get_info(&path);
47
48        let children: Vec<_> = children
49            .into_par_iter()
50            .map(|name| TreeBuilder {
51                path: join_path(&path, &name),
52                name,
53                get_info,
54                join_path,
55            })
56            .map(Self::from)
57            .collect();
58
59        DataTree::dir(name, size, children)
60    }
61}