file_ext/lib.rs
1use std::fs::{File};
2use crate::date_time_ext::DateTimeExt;
3use crate::directory_ext_impl::DirectoryExtImpl;
4use crate::file_ext_impl::FileExtImpl;
5use crate::path_ext_impl::PathExtImpl;
6use crate::symbol::SYMBOL;
7use crate::symlink_ext_impl::SymlinkExtImpl;
8use crate::user_ext_impl::UserExtImpl;
9
10#[cfg(test)]
11mod tests;
12mod date_time_ext;
13mod symbol;
14mod file_ext_impl;
15mod path_ext_impl;
16mod directory_ext_impl;
17mod symlink_ext_impl;
18mod user_ext_impl;
19mod filter_string;
20
21pub struct FileExt;
22
23impl FileExt {
24
25 /// Returns portion of a file of specified range. Range described as starting from byte M up to byte N.
26 /// # Examples
27 ///
28 /// ```
29 /// use file_ext::FileExt;
30 /// #[test]
31 /// fn partial_read() {
32 /// let path = "test/index.html";
33 /// let file_raw_bytes = FileExt::read_file_partially(path, 4, 10).unwrap();
34 /// let content = String::from_utf8(file_raw_bytes).unwrap();
35 ///
36 /// let expected_content = "CTYPE h";
37 ///
38 /// assert_eq!(expected_content, content);
39 /// }
40 /// ```
41 pub fn read_file_partially(filepath: &str, start: u64, end: u64) -> Result<Vec<u8>, String> {
42 FileExtImpl::read_file_partially(filepath, start, end)
43 }
44
45 /// Returns file content
46 /// # Examples
47 ///
48 /// ```
49 /// use file_ext::FileExt;
50 /// #[test]
51 /// fn file_content() {
52 /// let path = "test/index.html";
53 /// let file_raw_bytes = FileExt::read_file(path).unwrap();
54 /// let content = String::from_utf8(file_raw_bytes).unwrap();
55 ///
56 /// let content_escaped_newline_carriage_return = str::replace(content.as_str(), "\r\n", "\n");
57 ///
58 /// let expected_content = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Title</title>\n</head>\n<body>\n\n</body>\n</html>";
59 ///
60 /// assert_eq!(expected_content, content_escaped_newline_carriage_return);
61 /// }
62 /// ```
63 pub fn read_file(filepath: &str) -> Result<Vec<u8>, String> {
64 FileExtImpl::read_file(filepath)
65 }
66
67 /// Returns file modification timestamp as nanoseconds in Unix epoch
68 /// # Examples
69 ///
70 /// ```
71 /// use std::{thread, time};
72 /// use file_ext::FileExt;
73 /// #[test]
74 /// fn modification_timestamp() {
75 ///
76 /// let content = "data".as_bytes();
77 /// let path = "modification_timestamp-test.content";
78 ///
79 /// FileExt::create_file(path).unwrap();
80 /// FileExt::write_file(path, content).unwrap();
81 ///
82 /// let does_exist = FileExt::does_file_exist(path);
83 /// assert!(does_exist);
84 ///
85 /// let modified_timestamp = FileExt::file_modified_utc(path).unwrap();
86 ///
87 /// let one_second = time::Duration::from_secs(1);
88 /// thread::sleep(one_second);
89 ///
90 /// FileExt::write_file(path, "\nnewline and some data".as_bytes()).unwrap();
91 ///
92 /// let after_update_modified_timestamp = FileExt::file_modified_utc(path).unwrap();
93 /// assert!(after_update_modified_timestamp > modified_timestamp);
94 ///
95 ///
96 /// FileExt::delete_file(path).unwrap();
97 /// let doesnt_exist = !FileExt::does_file_exist(path);
98 /// assert!(doesnt_exist);
99 /// }
100 /// ```
101 pub fn file_modified_utc(filepath: &str) -> Result<u128, String> {
102 let boxed_open = File::open(filepath);
103 if boxed_open.is_err() {
104 let error_msg = boxed_open.err().unwrap();
105 let error = format!("<p>Unable to open file: {}</p> <p>error: {}</p>", filepath, error_msg);
106 return Err(error)
107 }
108
109 let file : File = boxed_open.unwrap();
110 let boxed_metadata = file.metadata();
111 if boxed_metadata.is_err() {
112 let error_msg = boxed_metadata.err().unwrap();
113 let error = format!("<p>Unable to open file: {}</p> <p>error: {}</p>", filepath, error_msg);
114 return Err(error)
115 }
116 let metadata = boxed_metadata.unwrap();
117 let boxed_last_modified_time = metadata.modified();
118 if boxed_last_modified_time.is_err() {
119 let error_msg = boxed_last_modified_time.err().unwrap();
120 let error = format!("<p>Unable to open file: {}</p> <p>error: {}</p>", filepath, error_msg);
121 return Err(error)
122 }
123 let modified_time = boxed_last_modified_time.unwrap();
124 let nanos = DateTimeExt::_system_time_to_unix_nanos(modified_time);
125 Ok(nanos)
126 }
127
128 #[cfg(target_family = "unix")]
129 /// # Examples
130 ///
131 /// ```
132 /// use file_ext::FileExt;
133 /// #[test]
134 /// fn unix_path_delimiter() {
135 /// let expected = SYMBOL.slash.to_string();
136 /// let actual = FileExt::get_path_separator();
137 /// }
138 /// ```
139 pub fn get_path_separator() -> String {
140 PathExtImpl::get_path_separator()
141 }
142
143 #[cfg(target_family = "windows")]
144 /// # Examples
145 ///
146 /// ```
147 /// use file_ext::FileExt;
148 /// #[test]
149 /// fn unix_path_delimiter() {
150 /// let expected = SYMBOL.reverse_slash.to_string();
151 /// let actual = FileExt::get_path_separator();
152 /// }
153 /// ```
154 pub fn get_path_separator() -> String { PathExtImpl::get_path_separator() }
155
156 /// Will return absolute file path to the working directory
157 /// # Examples
158 ///
159 /// ```
160 /// use file_ext::FileExt;
161 /// #[test]
162 /// fn absolute_path_to_working_directory() {
163 /// let boxed_path = FileExt::working_directory();
164 /// assert!(boxed_path.is_ok());
165 /// let path = boxed_path.unwrap();
166 /// }
167 /// ```
168 pub fn working_directory() -> Result<String, String> {
169 PathExtImpl::working_directory()
170 }
171
172
173 /// Will return absolute file path to the working directory. Same as working_directory function. Kept here to preserve backward compatability.
174 /// # Examples
175 ///
176 /// ```
177 /// use file_ext::FileExt;
178 /// #[test]
179 /// fn absolute_path_to_working_directory() {
180 /// let boxed_path = FileExt::absolute_path_to_working_directory();
181 /// assert!(boxed_path.is_ok());
182 /// let path = boxed_path.unwrap();
183 /// }
184 /// ```
185 pub fn absolute_path_to_working_directory() -> Result<String, String> {
186 PathExtImpl::working_directory()
187 }
188
189
190 /// Will return absolute working directory path appended to the given string
191 /// # Examples
192 ///
193 /// ```
194 /// use file_ext::FileExt;
195 /// #[test]
196 /// fn absolute_path_to_working_directory() {
197 /// let boxed_path = FileExt::get_static_filepath("");
198 /// assert!(boxed_path.is_ok());
199 /// let path = boxed_path.unwrap();
200 /// }
201 /// ```
202 pub fn get_static_filepath(path: &str) -> Result<String, String> {
203 let boxed_working_directory = PathExtImpl::absolute_path_to_working_directory();
204 if boxed_working_directory.is_err() {
205 let message = boxed_working_directory.err().unwrap();
206 return Err(message)
207 }
208
209 let working_directory = boxed_working_directory.unwrap();
210 let absolute_path = [working_directory, path.to_string()].join(SYMBOL.empty_string);
211 Ok(absolute_path)
212 }
213
214 /// Will try to read from file. If file does not exist, will create and write to it given byte array
215 /// # Examples
216 ///
217 /// ```
218 /// use file_ext::FileExt;
219 /// #[test]
220 /// fn read_or_create_and_write() {
221 /// let content = "data".as_bytes();
222 /// let tmp_folder = FileExt::get_temp_folder_path().unwrap();
223 ///
224 /// let path = [tmp_folder, "test.txt".to_string()].join(FileExt::get_path_separator().as_str());
225 ///
226 /// let doesnt_exist = !FileExt::does_file_exist(path.as_str());
227 /// assert!(doesnt_exist);
228 ///
229 /// FileExt::read_or_create_and_write(path.as_str(), content).unwrap();
230 ///
231 /// let does_exist = FileExt::does_file_exist(path.as_str());
232 /// assert!(does_exist);
233 ///
234 /// let new_content = "updated data".as_bytes();
235 /// FileExt::read_or_create_and_write(path.as_str(), new_content).unwrap();
236 ///
237 /// let file_content = FileExt::read_file(path.as_str()).unwrap();
238 /// assert_eq!(content, file_content);
239 ///
240 /// FileExt::delete_file(path.as_str()).unwrap();
241 /// let doesnt_exist = !FileExt::does_file_exist(path.as_str());
242 /// assert!(doesnt_exist);
243 /// }
244 /// ```
245 pub fn read_or_create_and_write(path: &str, content: &[u8]) -> Result<Vec<u8>, String> {
246 FileExtImpl::read_or_create_and_write(path, content)
247 }
248
249 /// Will create a file on the path
250 /// # Examples
251 ///
252 /// ```
253 /// use file_ext::FileExt;
254 /// #[test]
255 /// fn file_creation_deletion() {
256 /// let path = "test/file-creation.txt";
257 ///
258 /// let exists = FileExt::does_file_exist(path);
259 /// assert!(!exists);
260 ///
261 /// FileExt::create_file(path).unwrap();
262 ///
263 /// let content = FileExt::read_file(path).unwrap();
264 /// assert_eq!(content.len(), 0);
265 ///
266 /// FileExt::delete_file(path).unwrap();
267 ///
268 /// let exists = FileExt::does_file_exist(path);
269 /// assert!(!exists);
270 /// }
271 /// ```
272 pub fn create_file(path: &str) -> Result<(), String> {
273 FileExtImpl::create_file(path)
274 }
275
276 /// Returns boolean indicating file existence on the path
277 /// # Examples
278 ///
279 /// ```
280 /// use file_ext::FileExt;
281 /// #[test]
282 /// fn file_exists() {
283 /// let path = "test/index_rewrite";
284 /// let exists = FileExt::does_file_exist(path);
285 /// assert!(exists);
286 /// }
287 /// ```
288 pub fn does_file_exist(path: &str) -> bool {
289 FileExtImpl::does_file_exist(path)
290 }
291
292 /// Returns boolean indicating directory existence on the path
293 /// # Examples
294 ///
295 /// ```
296 /// use file_ext::FileExt;
297 /// #[test]
298 /// fn directory_exists() {
299 /// let path = "test";
300 /// let exists = FileExt::does_directory_exist(path);
301 /// assert!(exists);
302 /// }
303 /// ```
304 pub fn does_directory_exist(path: &str) -> bool {
305 DirectoryExtImpl::does_directory_exist(path)
306 }
307
308
309 /// Will create a new directory on specified path
310 /// # Examples
311 ///
312 /// ```
313 /// use file_ext::FileExt;
314 /// #[test]
315 /// fn new_directory_create_delete() {
316 /// let path = "new_directory";
317 ///
318 /// let boxed_create = FileExt::create_directory(path);
319 /// assert!(boxed_create.is_ok());
320 ///
321 /// assert!(FileExt::does_directory_exist(path));
322 ///
323 /// let boxed_delete = FileExt::delete_directory(path);
324 /// assert!(boxed_delete.is_ok());
325 /// }
326 /// ```
327 pub fn create_directory(path: &str) -> Result<(), String> {
328 DirectoryExtImpl::create_directory(path)
329 }
330
331 /// Will delete directory and all of the content on specified path (won't follow symlinks)
332 /// # Examples
333 ///
334 /// ```
335 /// use file_ext::FileExt;
336 /// #[test]
337 /// fn new_directory_create_delete() {
338 /// let path = "new_directory";
339 ///
340 /// let boxed_create = FileExt::create_directory(path);
341 /// assert!(boxed_create.is_ok());
342 ///
343 /// assert!(FileExt::does_directory_exist(path));
344 ///
345 /// let boxed_delete = FileExt::delete_directory(path);
346 /// assert!(boxed_delete.is_ok());
347 /// }
348 /// ```
349 pub fn delete_directory(path: &str) -> Result<(), String> {
350 DirectoryExtImpl::delete_directory(path)
351 }
352
353
354 /// Returns boolean indicating symlink existence on the path
355 /// # Examples
356 ///
357 /// ```
358 /// use file_ext::FileExt;
359 /// #[test]
360 /// fn symlink_exists() {
361 /// let symlink_path = ["test", "index-link2"].join(FileExt::get_path_separator().as_str());
362 ///
363 /// if FileExt::does_symlink_exist(symlink_path.as_str()) {
364 /// FileExt::delete_file(symlink_path.as_str()).unwrap();
365 /// }
366 ///
367 /// let path = [SYMBOL.empty_string, "test", SYMBOL.empty_string].join(FileExt::get_path_separator().as_str());
368 /// let path_prefix = FileExt::get_static_filepath(path.as_str()).unwrap();
369 /// let points_to = [path_prefix.to_string(), "index.html".to_string()].join("");
370 ///
371 /// let boxed_symlink = FileExt::create_symlink(
372 /// path_prefix.as_str(),
373 /// "index-link2",
374 /// points_to.as_str()
375 /// );
376 ///
377 ///
378 /// assert!(boxed_symlink.is_ok());
379 ///
380 /// let symlink_created = FileExt::does_symlink_exist(symlink_path.as_str());
381 /// assert!(symlink_created);
382 ///
383 /// let actual_points_to = FileExt::symlink_points_to(symlink_path.as_str()).unwrap();
384 /// assert_eq!(points_to, actual_points_to);
385 ///
386 /// FileExt::delete_file(symlink_path.as_str()).unwrap();
387 /// }
388 /// ```
389 pub fn does_symlink_exist(path: &str) -> bool {
390 SymlinkExtImpl::does_symlink_exist(path)
391 }
392
393 /// Returns absolute path, symlink points to.
394 /// Takes 2 parameters: path to the directory, where symlink is located and where symlink points to
395 /// # Examples
396 ///
397 /// ```
398 /// use file_ext::FileExt;
399 /// #[test]
400 /// fn resolve_symlink_path() {
401 /// let base_dir = "/home/someuser/folder/subfolder/subsubfolder";
402 /// let symlink_points_to = "../../subfolder2/subsubfolder2";
403 ///
404 /// let expected_path = "/home/someuser/folder/subfolder2/subsubfolder2";
405 /// let actual_path = FileExt::resolve_symlink_path(base_dir, symlink_points_to).unwrap();
406 ///
407 /// assert_eq!(expected_path, actual_path);
408 /// }
409 /// ```
410 pub fn resolve_symlink_path(symlink_directory: &str, symlink_points_to: &str) -> Result<String, String> {
411 SymlinkExtImpl::resolve_symlink_path(symlink_directory, symlink_points_to)
412 }
413
414 /// Will write given byte array to a file on the path
415 /// # Examples
416 /// ```
417 /// use file_ext::FileExt;
418 /// #[test]
419 /// fn write() {
420 /// let filename = "write-test.content";
421 /// FileExt::create_file(filename).unwrap();
422 ///
423 /// let expected_content = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Title</title>\n</head>\n<body>\n\n</body>\n</html>";
424 /// FileExt::write_file(filename, expected_content.as_bytes()).unwrap();
425 ///
426 /// let actual = FileExt::read_file(filename).unwrap();
427 /// assert_eq!(actual, expected_content.as_bytes());
428 ///
429 /// }
430 /// ```
431 pub fn write_file(path: &str, file_content: &[u8]) -> Result<(), String> {
432 FileExtImpl::write_file(path, file_content)
433 }
434
435 /// Will delete file on a given path
436 /// # Examples
437 ///
438 /// ```
439 /// use file_ext::FileExt;
440 /// #[test]
441 /// fn file_creation_deletion() {
442 /// let path = "test/file-creation.txt";
443 ///
444 /// let exists = FileExt::does_file_exist(path);
445 /// assert!(!exists);
446 ///
447 /// FileExt::create_file(path).unwrap();
448 ///
449 /// let content = FileExt::read_file(path).unwrap();
450 /// assert_eq!(content.len(), 0);
451 ///
452 /// FileExt::delete_file(path).unwrap();
453 ///
454 /// let exists = FileExt::does_file_exist(path);
455 /// assert!(!exists);
456 /// }
457 /// ```
458 pub fn delete_file(path: &str) -> Result<(), String> {
459 FileExtImpl::delete_file(path)
460 }
461
462 /// Will create symlink on path `symlink_path` with the specified name `symlink_name`.
463 /// Symlink will point to specific file or directory `symlink_points_to`. Paths are absolute.
464 /// # Examples
465 /// ```
466 /// use file_ext::FileExt;
467 /// #[test]
468 ///fn symlink_creation() {
469 /// let symlink_path = "test/index-link";
470 ///
471 /// if FileExt::does_symlink_exist(symlink_path) {
472 /// FileExt::delete_file(symlink_path).unwrap();
473 /// }
474 ///
475 /// let path_prefix = FileExt::get_static_filepath("/test/").unwrap();
476 /// let points_to = [path_prefix.to_string(), "index.html".to_string()].join("");
477 ///
478 /// let boxed_symlink = FileExt::create_symlink(
479 /// path_prefix.as_str(),
480 /// "index-link",
481 /// points_to.as_str());
482 ///
483 /// assert!(boxed_symlink.is_ok());
484 ///
485 /// let symlink_created = FileExt::does_symlink_exist(symlink_path);
486 /// assert!(symlink_created);
487 ///
488 /// let actual_points_to = FileExt::symlink_points_to(symlink_path).unwrap();
489 /// assert_eq!(points_to, actual_points_to);
490 ///
491 /// FileExt::delete_file(symlink_path).unwrap();
492 ///}
493 ///```
494 #[cfg(target_family = "unix")]
495 pub fn create_symlink(symlink_path: &str, symlink_name: &str, symlink_points_to: &str) -> Result<(), String> {
496 SymlinkExtImpl::create_symlink(symlink_path, symlink_name, symlink_points_to)
497 }
498
499
500 /// Will create symlink on path `symlink_path` with the specified name `symlink_name`.
501 /// Symlink will point to specific file or directory `symlink_points_to`. Paths are absolute.
502 /// # Examples
503 /// ```
504 /// use file_ext::FileExt;
505 /// #[test]
506 ///fn symlink_creation() {
507 /// let symlink_path = "test/index-link";
508 ///
509 /// if FileExt::does_symlink_exist(symlink_path) {
510 /// FileExt::delete_file(symlink_path).unwrap();
511 /// }
512 ///
513 /// let path_prefix = FileExt::get_static_filepath("/test/").unwrap();
514 /// let points_to = [path_prefix.to_string(), "index.html".to_string()].join("");
515 ///
516 /// let boxed_symlink = FileExt::create_symlink(
517 /// path_prefix.as_str(),
518 /// "index-link",
519 /// points_to.as_str());
520 ///
521 /// assert!(boxed_symlink.is_ok());
522 ///
523 /// let symlink_created = FileExt::does_symlink_exist(symlink_path);
524 /// assert!(symlink_created);
525 ///
526 /// let actual_points_to = FileExt::symlink_points_to(symlink_path).unwrap();
527 /// assert_eq!(points_to, actual_points_to);
528 ///
529 /// FileExt::delete_file(symlink_path).unwrap();
530 ///}
531 ///```
532 #[cfg(target_family = "windows")]
533 pub fn create_symlink(symlink_path: &str, symlink_name: &str, symlink_points_to: &str) -> Result<(), String> {
534 SymlinkExtImpl::create_symlink(symlink_path, symlink_name, symlink_points_to)
535 }
536
537 /// Checks if the file is symlink
538 /// # Examples
539 ///
540 /// ```
541 /// use file_ext::FileExt;
542 /// #[test]
543 /// fn is_link() {
544 /// let path: String = ["test", "index_rewrite"].join(&FileExt::get_path_separator());
545 /// let is_symlink = FileExt::is_symlink(path.as_str()).unwrap();
546 /// assert!(is_symlink);
547 /// }
548 /// ```
549 pub fn is_symlink(path: &str) -> Result<bool, String> {
550 SymlinkExtImpl::is_symlink(path)
551 }
552
553 /// Returns path to a file, symlink points to
554 /// # Examples
555 ///
556 /// ```
557 /// use file_ext::FileExt;
558 /// #[test]
559 /// fn link_points_to() {
560 /// let path: String = ["test", "index_rewrite"].join(&FileExt::get_path_separator());
561 /// let points_to = FileExt::symlink_points_to(path.as_str()).unwrap();
562 /// assert_eq!("index.html", points_to);
563 /// }
564 /// ```
565 pub fn symlink_points_to(path: &str) -> Result<String, String> {
566 SymlinkExtImpl::symlink_points_to(path)
567 }
568
569 /// Builds a path from a given node list
570 /// # Examples
571 ///
572 /// ```
573 /// use file_ext::FileExt;
574 ///
575 /// #[test]
576 /// #[cfg(target_family = "unix")]
577 /// fn build_path() {
578 /// let root = FileExt::root();
579 /// let folder_up = FileExt::folder_up();
580 ///
581 /// let node_list =
582 /// [
583 /// root.as_str(),
584 /// "home",
585 /// "someuser",
586 /// "folder",
587 /// "subfolder",
588 /// "subsubfolder",
589 /// ];
590 ///
591 /// let another_node_list =
592 /// [
593 /// folder_up.as_str(),
594 /// folder_up.as_str(),
595 /// "subfolder2",
596 /// "subsubfolder2",
597 /// ];
598 /// let path = PathExtImpl::build_path(&node_list);
599 /// let another_path = PathExtImpl::build_path(&another_node_list);
600 ///
601 /// assert_eq!("/home/someuser/folder/subfolder/subsubfolder", path);
602 /// assert_eq!("../../subfolder2/subsubfolder2", another_path);
603 /// }
604 ///
605 ///
606 /// #[test]
607 /// #[cfg(target_family = "windows")]
608 /// fn build_path() {
609 /// let root = FileExt::root();
610 /// let folder_up = FileExt::folder_up();
611 ///
612 /// let node_list =
613 /// [
614 /// root.as_str(),
615 /// "Users",
616 /// "someuser",
617 /// "folder",
618 /// "subfolder",
619 /// "subsubfolder",
620 /// ];
621 ///
622 /// let path = PathExtImpl::build_path(&node_list);
623 ///
624 /// assert_eq!("C:\\Users\\someuser\\folder\\subfolder\\subsubfolder", path);
625 /// }
626 /// ```
627 pub fn build_path(list: &[&str]) -> String {
628 PathExtImpl::build_path(list)
629 }
630
631 /// Root node of the system. It is meant to be used in `build_path` function.
632 /// On Linux and macOS `build_path` function will evaluate it to `/`,
633 /// on Windows it will be `C:`
634 pub fn root() -> String {
635 PathExtImpl::root()
636 }
637
638
639 /// Folder up, or `..`. It is meant to be used in `build_path` function.
640 pub fn folder_up() -> String {
641 PathExtImpl::folder_up()
642 }
643
644 /// Returns name of the user running the process
645 /// # Examples
646 ///
647 /// ```
648 /// use file_ext::FileExt;
649 /// #[test]
650 /// #[cfg(target_family = "unix")]
651 /// fn current_user() {
652 /// let boxed_user = FileExt::get_current_user();
653 /// assert!(boxed_user.is_ok());
654 ///
655 /// let user = boxed_user.unwrap();
656 /// }
657 /// ```
658 #[cfg(target_family = "unix")]
659 pub fn get_current_user() -> Result<String, String> {
660 UserExtImpl::get_current_user()
661 }
662
663 /// Returns name of the user running the process
664 /// # Examples
665 ///
666 /// ```
667 /// use file_ext::FileExt;
668 /// #[test]
669 /// #[cfg(target_family = "windows")]
670 /// fn current_user() {
671 /// let boxed_user = FileExt::get_current_user();
672 /// assert!(boxed_user.is_ok());
673 ///
674 /// let user = boxed_user.unwrap();
675 /// }
676 /// ```
677 #[cfg(target_family = "windows")]
678 pub fn get_current_user() -> Result<String, String> {
679 UserExtImpl::get_current_user()
680 }
681
682 /// Returns domain of the user running the process
683 /// # Examples
684 ///
685 /// ```
686 /// use file_ext::FileExt;
687 /// #[test]
688 /// #[cfg(target_family = "windows")]
689 /// fn current_user() {
690 /// let boxed_user_domain = FileExt::get_current_user_domain();
691 /// assert!(boxed_user_domain.is_ok());
692 ///
693 /// let domain = boxed_user_domain.unwrap();
694 /// }
695 /// ```
696 #[cfg(target_family = "windows")]
697 pub fn get_current_user_domain() -> Result<String, String> {
698 UserExtImpl::get_current_user_domain()
699 }
700
701 /// Returns path to the temporary folder
702 /// # Examples
703 ///
704 /// ```
705 /// use file_ext::FileExt;
706 /// #[test]
707 /// #[cfg(target_family = "windows")]
708 /// fn temp_folder() {
709 /// let temp_folder_path = FileExt::get_temp_folder_path().unwrap();
710 /// assert!(temp_folder_path.starts_with("C:\\Users\\"));
711 /// assert!(temp_folder_path.ends_with("\\AppData\\Local\\Temp"));
712 /// }
713 /// ```
714 #[cfg(target_family = "windows")]
715 pub fn get_temp_folder_path() -> Result<String, String>{
716 PathExtImpl::get_temp_folder_path()
717 }
718
719 /// Returns path to the temporary folder
720 /// # Examples
721 ///
722 /// ```
723 /// use file_ext::FileExt;
724 /// #[test]
725 /// #[cfg(target_family = "unix")]
726 /// fn temp_folder() {
727 /// let temp_folder_path = FileExt::get_temp_folder_path().unwrap();
728 /// assert_eq!(temp_folder_path, "/tmp")
729 /// }
730 /// ```
731 #[cfg(target_family = "unix")]
732 pub fn get_temp_folder_path() -> Result<String, String>{
733 PathExtImpl::get_temp_folder_path()
734 }
735
736 /// Returns file length in bytes
737 ///```
738 /// use file_ext::FileExt;
739 /// #[test]
740 /// fn length() {
741 /// let expected_length: u64 = 398;
742 /// let pwd = FileExt::working_directory().unwrap();
743 /// let length = FileExt::file_length(vec![pwd.as_str(), "LICENSE"]).unwrap();
744 ///
745 /// assert_eq!(expected_length, length);
746 /// }
747 /// ```
748 pub fn file_length(path: Vec<&str>) -> Result<u64, String> {
749 FileExtImpl::file_length(path)
750 }
751
752 /// Copies file block by block. Block size is 100kb
753 ///```
754 /// use file_ext::FileExt;
755 /// #[test]
756 /// fn copy_file() {
757 /// let pwd = FileExt::working_directory().unwrap();
758 /// FileExt::copy_file(vec![pwd.as_str(), "LICENSE"], vec![pwd.as_str(), "LICENSE_copy2"]).unwrap();
759 ///
760 /// let path = FileExt::build_path(vec![pwd.as_str(), "LICENSE_copy2"].as_slice());
761 /// FileExt::delete_file(path.as_str()).unwrap();
762 /// }
763 /// ```
764 pub fn copy_file(from: Vec<&str>, to: Vec<&str>)-> Result<(), String> {
765 FileExtImpl::copy_file(from, to)
766 }
767
768 /// Copies file block by block. If block size is None it is set to 100kb.
769 /// Calls the progress callback at the beginning of the block copy.
770 /// Calls the cancel callback at the end of the block copy.
771 ///```
772 /// use file_ext::FileExt;
773 /// #[test]
774 /// fn copy_file_with_callback_and_block_size() {
775 /// let block_size : u64 = 1000000;
776 /// let pwd = FileExt::working_directory().unwrap();
777 /// let mut label = "".to_string();
778 /// let progress_callback = |start, end, total| { label = format!("copying block {}-{} of {} bytes", start, end, total).to_string(); };
779 /// let cancel_callback = |_start, _end, _total| { false };
780 /// FileExt::copy_file_with_callbacks(
781 /// vec![pwd.as_str(), "LICENSE"],
782 /// vec![pwd.as_str(), "LICENSE_copy3"],
783 /// Some(block_size),
784 /// progress_callback,
785 /// cancel_callback
786 /// ).unwrap();
787 ///
788 /// let path = FileExt::build_path(vec![pwd.as_str(), "LICENSE_copy3"].as_slice());
789 /// FileExt::delete_file(path.as_str()).unwrap();
790 /// }
791 ///```
792 pub fn copy_file_with_callbacks<F: FnMut(u64, u64, u64), C: FnMut(u64, u64, u64) -> bool>
793 (
794 from: Vec<&str>,
795 to: Vec<&str>,
796 block_size: Option<u64>,
797 progress_callback: F,
798 cancel_callback: C
799 )
800 -> Result<(), String> {
801 FileExtImpl::copy_file_with_callbacks(from, to, block_size, progress_callback, cancel_callback)
802 }
803
804 /// Copies file block by block starting from specific byte. If block size is None it is set to 100kb.
805 /// Calls the progress callback at the beginning of the block copy.
806 /// Calls the cancel callback at the end of the block copy.
807 ///```
808 /// use file_ext::FileExt;
809 /// #[test]
810 /// fn copy_file_with_callback_and_block_size_starting_from_byte() {
811 /// let block_size : u64 = 1000000;
812 /// let pwd = FileExt::working_directory().unwrap();
813 /// let mut label = "".to_string();
814 /// let progress_callback = |start, end, total| { label = format!("copying block {}-{} of {} bytes", start, end, total).to_string(); };
815 /// let cancel_callback = |_start, _end, _total| { false };
816 /// let starting_byte = 4;
817 /// FileExt::copy_file_with_callbacks_starting_from_byte(
818 /// vec![pwd.as_str(), "LICENSE"],
819 /// vec![pwd.as_str(), "LICENSE_copy4"],
820 /// starting_byte,
821 /// Some(block_size),
822 /// progress_callback,
823 /// cancel_callback
824 /// ).unwrap();
825 ///
826 /// let path = FileExt::build_path(vec![pwd.as_str(), "LICENSE_copy4"].as_slice());
827 /// FileExt::delete_file(path.as_str()).unwrap();
828 /// }
829 ///```
830 pub fn copy_file_with_callbacks_starting_from_byte
831 <F: FnMut(u64, u64, u64), C: FnMut(u64, u64, u64) -> bool>
832 (
833 from: Vec<&str>,
834 to: Vec<&str>,
835 starting_byte: u64,
836 block_size: Option<u64>,
837 progress_callback: F,
838 cancel_callback: C,
839 )
840 -> Result<(), String> {
841 FileExtImpl::copy_file_with_callbacks_starting_from_byte(from, to, starting_byte, block_size, progress_callback, cancel_callback)
842 }
843
844 /// Copies file block by block starting from specific byte up to ending byte.
845 /// If block size is None it is set to 100kb.
846 /// Calls the progress callback at the beginning of the block copy.
847 /// Calls the cancel callback at the end of the block copy.
848 ///```
849 /// use file_ext::FileExt;
850 /// #[test]
851 /// fn copy_file_with_callback_and_block_size_starting_from_byte_to_ending_byte() {
852 /// let block_size : u64 = 1000000;
853 /// let pwd = FileExt::working_directory().unwrap();
854 /// let mut label = "".to_string();
855 /// let progress_callback = |start, end, total| { label = format!("copying block {}-{} of {} bytes", start, end, total).to_string(); };
856 /// let cancel_callback = |_start, _end, _total| { false };
857 /// let starting_byte = 4;
858 /// let ending_byte = 10;
859 /// FileExt::copy_file_with_callbacks_starting_from_byte_and_ending_at_byte(
860 /// vec![pwd.as_str(), "LICENSE"],
861 /// vec![pwd.as_str(), "LICENSE_copy5"],
862 /// starting_byte,
863 /// ending_byte,
864 /// Some(block_size),
865 /// progress_callback,
866 /// cancel_callback
867 /// ).unwrap();
868 ///
869 /// let path = FileExt::build_path(vec![pwd.as_str(), "LICENSE_copy5"].as_slice());
870 /// FileExt::delete_file(path.as_str()).unwrap();
871 /// }
872 ///```
873 pub fn copy_file_with_callbacks_starting_from_byte_and_ending_at_byte
874 <F: FnMut(u64, u64, u64), C: FnMut(u64, u64, u64) -> bool>
875 (
876 from: Vec<&str>,
877 to: Vec<&str>,
878 starting_byte: u64,
879 ending_byte: u64,
880 block_size: Option<u64>,
881 progress_callback: F,
882 cancel_callback: C,
883 )
884 -> Result<(), String>
885 {
886 FileExtImpl::copy_file_with_callbacks_starting_from_byte_and_ending_at_byte(from, to, starting_byte, ending_byte, block_size, progress_callback, cancel_callback)
887 }
888}
889