Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_file/src/tree.rs

2.5 KiB, 5 runs

created by r1870400018:304, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_core::{
2 prelude::*,
3};
4use oxedyne_fe2o3_data::tree::{
5 Branch,
6 Leaf,
7 Node,
8 NodeData,
9 Tree,
10};
11
12use std::{
13 fs,
14 path::{
15 Path,
16 PathBuf,
17 },
18 time::SystemTime,
19};
20
21
22#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
23pub struct Attributes {
24 path: PathBuf,
25 mod_time: SystemTime,
26 size: u64,
27}
28
29impl NodeData for Attributes {}
30
31new_type!(FileTree, Tree<PathBuf, Attributes>, Clone, Debug);
32
33impl FileTree {
34
35 pub fn new<P: AsRef<Path>>(path: P) -> Outcome<Self> {
36 let root = path.as_ref().to_path_buf();
37 let nodes = res!(Self::read_nodes(&root));
38 // Max theoretical directory depth estimates resulting from path length limits:
39 // Linux: 2047,
40 // Windows: 129 (default),
41 // MacOS: 507
42 let mut tree = Tree::new(
43 root,
44 nodes,
45 2048,
46 );
47 tree.sort_by_name();
48 res!(tree.set_node_focus(true));
49 Ok(Self(tree))
50 }
51
52 pub fn read_nodes(
53 path: &Path,
54 )
55 -> Outcome<Vec<Node<Attributes>>>
56 {
57 let mut nodes = Vec::new();
58
59 for entry_result in res!(fs::read_dir(path), IO, File) {
60 let entry = res!(entry_result, IO, File);
61 let node_type = res!(entry.file_type(), IO, File);
62 let node_path = entry.path();
63 let metadata = res!(entry.metadata(), IO, File);
64 let size = metadata.len();
65 let mod_time = metadata.modified().unwrap_or(SystemTime::UNIX_EPOCH);
66
67 let node_name = match entry.file_name().to_str() {
68 Some(name) => name.to_string(),
69 None => String::from(""),
70 };
71
72 let data = Attributes {
73 path: node_path.clone(),
74 size,
75 mod_time,
76 };
77 if node_type.is_file() {
78 nodes.push(Node::Leaf(Leaf {
79 name: node_name,
80 data,
81 focus: false,
82 selected: false,
83 }));
84 } else if node_type.is_dir() {
85 let subdir_nodes = res!(Self::read_nodes(&node_path));
86 nodes.push(Node::Branch(Branch {
87 name: node_name,
88 data,
89 nodes: subdir_nodes,
90 expanded: false,
91 focus: false,
92 selected: false,
93 }));
94 }
95 }
96
97 Ok(nodes)
98 }
99}