command_fs/
file_perform.rs

1use super::file_handel::CommandFS;
2use std::{
3    borrow::BorrowMut,
4    ops::{AddAssign, ShlAssign, Shr, ShrAssign, SubAssign},
5    path::Path,
6};
7use tokio::fs;
8
9impl<'a> CommandFS<'a> {
10    /**
11    ```rust
12    let mut command = CommandFS::new("/");
13    ```
14      It will create CommandFS struct which contain two Field. file_dir (File or Directory),
15      err_msg (For Safety every error message is store in err_msg field)
16     */
17    pub fn new(dir: &'a str) -> Self {
18        Self {
19            dir: Path::new(dir),
20            // sample_dir: None,
21            err_msg: "".to_string(),
22        }
23    }
24    // Because it require some time to load large data
25    /**
26    ```rust
27    let mut command = CommandFS::new("/home/username"); // For Unix System
28    command.read_data(".bashrc"); // If you see Empty it means file Doesn't exist or something.
29    println!("{}", command.err_msg); // It'll print error message without any panic
30    ```
31     */
32    pub async fn read_data(&mut self, from_file: &str) -> Vec<u8> {
33        match fs::read(self.whereami().to_owned() + "/" + from_file).await {
34            Ok(file) => file,
35            Err(error) => {
36                self.err_msg = error.to_string();
37                vec![]
38            }
39        }
40    }
41    /**
42     ```rust
43    let mut command = CommandFS::new("/home/username"); // For Unix System
44    command.read_data(".bashrc").await; // If you see Empty it means file Doesn't exist or something.
45     ```
46    */
47    pub async fn write_data(&mut self, data: Vec<u8>, to_file: &'a str) {
48        if self.dir.is_dir() {
49            match fs::write(format!("{}/{to_file}", self.whereami()), data).await {
50                Ok(_) => {}
51                Err(error) => self.err_msg = error.to_string(),
52            }
53        } else {
54            self.err_msg = String::from(
55                "!WARNING! Seems like Given path is file please set path to Directory on given",
56            );
57        }
58    }
59    pub fn change_dir(&mut self, dir: &'a str) {
60        if Path::new(dir).is_dir() {
61            self.dir = Path::new(dir)
62        } else {
63            self.err_msg =
64                "!ERROR! Change Dir failed cause given Path is file or not exist".to_string()
65        }
66    }
67    pub fn step_back(&mut self, step: usize) {
68        let mut current_step = step;
69        let current_dir = self.whereami().to_owned();
70        let mut splited: Vec<&str> = current_dir.split('/').filter(|s| !s.is_empty()).collect();
71        let mut updated_path = "".to_string();
72        {
73            while current_step != 0 {
74                match splited.pop() {
75                    Some(_) => {}
76                    None => {
77                        self.err_msg = "!WARNING! it can't step back more".to_string();
78                        self.dir = Path::new("/");
79                        break;
80                    }
81                }
82                current_step -= 1
83            }
84        }
85        for each in &splited {
86            updated_path.push_str(&("/".to_owned() + each));
87        }
88        if splited.len() == 0 {
89            self.change_dir(Box::leak(Box::new("/")))
90        } else {
91            self.change_dir(Box::leak(Box::new(updated_path)))
92        }
93    }
94
95    fn write_data_sync(&mut self, data: Vec<u8>, to_file: &'a str) {
96        if self.dir.is_dir() {
97            match std::fs::write(format!("{}/{to_file}", self.whereami()), data) {
98                Ok(_) => {}
99                Err(error) => self.err_msg = error.to_string(),
100            }
101        } else {
102            self.err_msg = String::from(
103                "!WARNING! Seems like Given path is file please set path to Directory on given",
104            );
105        }
106    }
107    pub async fn remove(&mut self, file: &str) {
108        let target_path = self.whereami().to_owned() + "/" + file;
109        if Path::new(target_path.as_str()).is_dir() {
110            match fs::remove_dir(target_path.as_str()).await {
111                Ok(_) => {}
112                Err(error) => self.err_msg = error.to_string(),
113            }
114        } else {
115            match fs::remove_file(target_path.as_str()).await {
116                Ok(_) => {}
117                Err(error) => self.err_msg = error.to_string(),
118            }
119        }
120    }
121    fn remove_sync(&mut self, path: &str) {
122        let target_path = self.whereami().to_owned() + path;
123        if Path::new(target_path.as_str()).is_dir() {
124            match std::fs::remove_dir(target_path.as_str()) {
125                Ok(_) => {}
126                Err(error) => self.err_msg = error.to_string(),
127            }
128        } else {
129            match std::fs::remove_file(target_path.as_str()) {
130                Ok(_) => {}
131                Err(error) => self.err_msg = error.to_string(),
132            }
133        }
134    }
135    fn read_data_sync(&mut self, from_file: &str) -> Vec<u8> {
136        match std::fs::read(self.whereami().to_owned() + "/" + from_file) {
137            Ok(file) => file,
138            Err(error) => {
139                self.err_msg = error.to_string();
140                vec![]
141            }
142        }
143    }
144    fn create_dir(&mut self, dir_name: &'a str) {
145        match std::fs::create_dir(format!("{}/{dir_name}", self.whereami())) {
146            Ok(_) => {}
147            Err(error) => self.err_msg = error.to_string(),
148        }
149    }
150    pub fn rename(&mut self, from_file: &str, rename: &str) {
151        let mut count = 0;
152        let mut file_found = false;
153        while self.file_list().len() != count - 1 {
154            if self.file_list()[count] != from_file.to_string() {
155                count += 1;
156            } else {
157                match std::fs::rename(
158                    self.whereami().to_owned() + "/" + from_file,
159                    self.whereami().to_owned() + "/" + rename,
160                ) {
161                    Ok(_) => {}
162                    Err(error) => self.err_msg = error.to_string(),
163                };
164                file_found = true;
165                break;
166            }
167        }
168        if !file_found {
169            self.err_msg = format!(
170                "!NOT FOUND! from the currrent path, {} file is not available",
171                from_file
172            )
173        }
174    }
175}
176
177/**
178    ```rust
179let mut command = CommandFS::new("/home/username");
180command += ("myfile.txt", b"Blah Blah Blah Blah");
181```
182      It will create Create and Write File for non sync task for known Size.
183*/
184impl<'a, const N: usize> AddAssign<(&'a str, &[u8; N])> for CommandFS<'a> {
185    fn add_assign(&mut self, rhs: (&'a str, &[u8; N])) {
186        self.write_data_sync(rhs.1.to_vec(), rhs.0);
187    }
188}
189
190/**
191    ```rust
192let mut command = CommandFS::new("/home/username");
193command += ("myfile.txt", vec![66, 108, 97, 104,32,66, 108, 97, 104,32,66, 108, 97, 104,32,66, 108, 97, 104,32].as_bytes());
194```
195      It will create Create and Write File for non sync task but different is unknown Size.
196*/
197impl<'a> AddAssign<(&'a str, &[u8])> for CommandFS<'a> {
198    fn add_assign(&mut self, rhs: (&'a str, &[u8])) {
199        self.write_data_sync(rhs.1.to_vec(), rhs.0);
200    }
201}
202
203/**
204    ```rust
205let mut command = CommandFS::new("/home/username");
206command += ("mydirectory");
207    ```
208      It will create Directory,
209*/
210impl<'a> AddAssign<&'a str> for CommandFS<'a> {
211    fn add_assign(&mut self, rhs: &'a str) {
212        self.create_dir(rhs)
213    }
214}
215
216impl<'a> ShrAssign<&str> for CommandFS<'a> {
217    fn shr_assign(&mut self, rhs: &str) {
218        let updated_dir = self.whereami().to_owned() + rhs;
219        self.borrow_mut()
220            .change_dir(Box::leak(Box::new(updated_dir)));
221    }
222}
223
224impl<'a> SubAssign<&str> for CommandFS<'a> {
225    fn sub_assign(&mut self, rhs: &str) {
226        self.remove_sync(rhs)
227    }
228}
229
230impl<'a> ShlAssign<usize> for CommandFS<'a> {
231    fn shl_assign(&mut self, rhs: usize) {
232        self.step_back(rhs);
233    }
234}
235
236impl<'a> Shr<&str> for &mut CommandFS<'a> {
237    type Output = Vec<u8>;
238    fn shr(self, rhs: &str) -> Self::Output {
239        (&mut self.read_data_sync(rhs)).clone()
240    }
241}