cyfs_util/util/
dir_loader.rs1use cyfs_base::*;
2
3use std::fs;
4use std::path::{Path, PathBuf};
5
6pub struct DirObjectsSyncLoader {
7 roots: Vec<PathBuf>,
8 objects: Vec<(PathBuf, Vec<u8>)>,
9}
10
11impl DirObjectsSyncLoader {
12 pub fn new(root: impl Into<PathBuf>) -> Self {
13 Self {
14 roots: vec![root.into()],
15 objects: Vec::new(),
16 }
17 }
18
19 pub fn into_objects(self) -> Vec<(PathBuf, Vec<u8>)> {
20 self.objects
21 }
22
23 pub fn load(&mut self) {
24 let mut i = 0;
25 loop {
26 if i >= self.roots.len() {
27 break;
28 }
29
30 let root = self.roots[i].clone();
31 let _ = self.scan_root(&root);
32
33 i += 1;
34 }
35 }
36
37 fn scan_root(&mut self, root: &Path) -> BuckyResult<()> {
38 if !root.is_dir() {
39 return Ok(());
40 }
41
42 let mut entries = fs::read_dir(root).map_err(|e| {
43 error!(
44 "read object dir failed! dir={}, {}",
45 root.display(),
46 e
47 );
48 e
49 })?;
50
51 while let Some(res) = entries.next() {
52 let entry = res.map_err(|e| {
53 error!("read entry error: {}", e);
54 e
55 })?;
56
57 let file_path = root.join(entry.file_name());
58 if file_path.is_dir() {
59 self.roots.push(file_path);
60 continue;
61 }
62
63 if !file_path.is_file() {
64 warn!("path is not file: {}", file_path.display());
65 continue;
66 }
67
68 if !Self::is_desc_file(&file_path) {
69 debug!("not desc file: {}", file_path.display());
70 continue;
71 }
72
73 if let Ok(ret) = self.load_file(&file_path) {
74 self.objects.push((file_path, ret));
75 }
76 }
77
78 Ok(())
79 }
80
81 fn is_desc_file(file_path: &Path) -> bool {
82 match file_path.extension() {
83 Some(ext) => {
84 let ext = ext.to_string_lossy();
85
86 #[cfg(windows)]
87 let ext = ext.to_lowercase();
88
89 if ext == "desc" {
90 true
91 } else {
92 false
93 }
94 }
95 None => false,
96 }
97 }
98
99 fn load_file(&self, file: &Path) -> BuckyResult<Vec<u8>> {
100 let buf = fs::read(file).map_err(|e| {
101 error!("load object from file failed! file={}, {}", file.display(), e);
102 e
103 })?;
104
105 Ok(buf)
106 }
107}