1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
use super::{sorted_entries, EntryDataBundle, SortMode};
use crate::interactive::path_of;
use dua::traverse::{EntryData, Traversal, Tree, TreeIndex};
use petgraph::{visit::Bfs, Direction};
use std::path::{Path, PathBuf};
pub struct TreeView<'a> {
pub traversal: &'a mut Traversal,
pub glob_tree_root: Option<TreeIndex>,
}
impl TreeView<'_> {
pub fn tree(&self) -> &Tree {
&self.traversal.tree
}
pub fn tree_mut(&mut self) -> &mut Tree {
&mut self.traversal.tree
}
pub fn fs_parent_of(&self, idx: TreeIndex) -> Option<TreeIndex> {
self.traversal
.tree
.neighbors_directed(idx, petgraph::Incoming)
.find(|idx| match self.glob_tree_root {
None => true,
Some(glob_root) => *idx != glob_root,
})
}
pub fn view_parent_of(&self, idx: TreeIndex) -> Option<TreeIndex> {
let mut iter = self
.traversal
.tree
.neighbors_directed(idx, petgraph::Incoming);
match self.glob_tree_root {
None => iter.next(),
Some(glob_root) => iter
.clone()
.find(|idx| *idx == glob_root)
.or_else(|| iter.next()),
}
}
pub fn path_of(&self, node_idx: TreeIndex) -> PathBuf {
path_of(&self.traversal.tree, node_idx, self.glob_tree_root)
}
pub fn sorted_entries(&self, view_root: TreeIndex, sorting: SortMode) -> Vec<EntryDataBundle> {
sorted_entries(
&self.traversal.tree,
view_root,
sorting,
self.glob_tree_root,
)
}
pub fn current_path(&self, view_root: TreeIndex) -> String {
current_path(&self.traversal.tree, view_root, self.glob_tree_root)
}
pub fn remove_entries(&mut self, index: TreeIndex, remove_index: bool) -> usize {
let mut entries_deleted = 0;
let mut bfs = Bfs::new(self.tree(), index);
while let Some(nx) = bfs.next(&self.tree()) {
if nx == index && !remove_index {
continue;
}
self.tree_mut().remove_node(nx);
entries_deleted += 1;
}
entries_deleted
}
pub fn exists(&self, idx: TreeIndex) -> bool {
self.tree().node_weight(idx).is_some()
}
pub fn total_size(&self) -> u128 {
self.tree()
.neighbors_directed(self.traversal.root_index, Direction::Outgoing)
.filter_map(|idx| self.tree().node_weight(idx).map(|w| w.size))
.sum()
}
pub fn recompute_sizes_recursively(&mut self, mut index: TreeIndex) {
loop {
let (size_of_children, item_count) = self
.tree()
.neighbors_directed(index, Direction::Outgoing)
.filter_map(|idx| {
self.tree().node_weight(idx).map(|w| (w.size, w.entry_count.unwrap_or(1)))
})
.reduce(|a, b| (a.0 + b.0, a.1 + b.1))
.unwrap_or_default();
let node = self.traversal
.tree
.node_weight_mut(index)
.expect("valid index");
node.size = size_of_children;
node.entry_count = Some(item_count);
match self.fs_parent_of(index) {
None => break,
Some(parent) => index = parent,
}
}
}
}
fn current_path(
tree: &petgraph::stable_graph::StableGraph<EntryData, ()>,
root: petgraph::stable_graph::NodeIndex,
glob_root: Option<TreeIndex>,
) -> String {
match path_of(tree, root, glob_root).to_string_lossy().to_string() {
ref p if p.is_empty() => Path::new(".")
.canonicalize()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|_| String::from(".")),
p => p,
}
}
|