1use std::{fs, path::PathBuf, vec};
2use anyhow::{Ok, Result};
3
4#[derive(Debug, Clone)]
9pub struct WalkFileEntry{
10 pub root: PathBuf,
11 pub child_dirs: Vec<String>,
12 pub child_files: Vec<String>,
13}
14
15impl WalkFileEntry {
16 pub fn as_tuple_ref(&self)->(&PathBuf, &Vec::<String>, &Vec::<String>){
32 (&self.root, &self.child_dirs, &self.child_files)
33 }
34
35 pub fn as_tuple(&self)->(PathBuf, Vec::<String>, Vec::<String>){
51 (self.root.clone(), self.child_dirs.clone(), self.child_files.clone())
52 }
53}
54
55
56impl std::fmt::Display for WalkFileEntry {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "root: {}, child_dirs: {:?}, child_files:{:?}", self.root.display(), self.child_dirs, self.child_files)
60 }
61}
62
63pub fn walk(path: &PathBuf)->Result<Vec<WalkFileEntry>>{
78 let mut res:Vec<WalkFileEntry> = Vec::new();
79 walk_dir(path, &mut res)?;
80 Ok(res)
81}
82
83fn walk_dir(path: &PathBuf, res: &mut Vec<WalkFileEntry>)->Result<()>{
85 let mut walk = WalkFileEntry{
86 root: path.clone(),
87 child_dirs: vec![],
88 child_files: vec![],
89 };
90 for entry in fs::read_dir(path)?{
91 let entry = entry?;
92 if entry.path().is_dir(){
93 if let Some(p) = entry.path().file_name(){
94 if let Some(p_str) = p.to_str(){
95 walk.child_dirs.push(p_str.to_string());
96 }
97 }
98 walk_dir(&entry.path(), res)?;
99 }else if entry.path().is_file() {
100 if let Some(p) = entry.path().file_name(){
101 if let Some(p_file) = p.to_str(){
102 walk.child_files.push(p_file.to_string());
103 }
104 }
105 }
106 }
107 res.push(walk);
108 Ok(())
109}
110
111#[cfg(test)]
112mod test{
113 use std::{path::PathBuf, str::FromStr};
114
115 use crate::walk;
116
117 #[test]
118 fn test_walk(){
119 let res = walk(&PathBuf::from_str("./").unwrap());
120 let res = match res {
121 Err(e) => panic!("{}", e),
122 Ok(res) => res
123 };
124 print!("{:#?}", res);
125 }
126
127 #[test]
128 fn test_ref_tuple(){
129 let res = walk(&PathBuf::from_str("./").unwrap());
130 let res = match res {
131 Err(e) => panic!("{}", e),
132 Ok(res) => res
133 };
134 let (root, child_dirs, child_files) = res[0].as_tuple();
135 println!("{:?}, {:?}, {:?}", root, child_dirs, child_files);
136 }
137}