1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
pub mod files;
use self::files::{collect_folder, correct_path};
use super::get_file;
use crate::dpds_path::io::{self, ErrorKind, Write};
use crate::dpds_path::{DirBuilder, File, OpenOptions};

/// File/path option, preferred mode **auto**
///  # Paths syntax
///  - Windows 
///  > `".\\folder\\\folder\\file.txt"`
///  - linux
/// > `"./folder/folder/file.txt"`
///  - macos   (**doesn't work** with files with '/', "x/y/z.txt" in the name on macos)
/// > `"./folder/folder/file.txt"`
pub enum Flag {
    ///Creates a new path with file. Writes new data to an empty file
    /// # Examples
    /// ```
    ///   let path = "./Folder1/NewFolder1/file_new.txt";
    ///   
    ///   assert_eq!(file_write(path, "ok", Flag::New).unwrap(), file_read(path).unwrap());
    /// ```
    New,
    /// Auto option
    ///- If the path exists, regardless of the case, we work with the file `(Flag::Old)`
    ///
    ///> **The path we specified**: `"/Folder1/folDER2/file.TXT"`\
    /// **real path** : `"/Folder1/Folder2/file.txt"`\
    /// **Result** : `"/Folder1/Folder2/file.txt"`
    /// - If the file/path is not found, creates a new path with the file (*if initial path exists*) `(Flag::New)`
    ///
    ///> **The path we specified**: `"/Folder1/newFolder/file.TXT"`\
    /// **real path** : `"/Folder1/newFolder/file.txt"`\
    /// **Result** : `"/Folder1/newFolder/file.txt"`
    ///
    /// but if the initial path is case different, then a *new path with the file* is created `(Flag::New)`
    ///
    ///> **The path we specified**: `"/folder1/newFolder/file.TXT"`\
    /// **real path** : `"/folder1/newFolder/file.txt"`\
    /// **Result** : `"/folder1/newFolder/file.txt"`
    /// # Examples
    /// ```
    ///   let path = "./Folder1/not_existing_folder/file_new.txt";
    ///   
    ///   assert_eq!(file_write(path, "ok", Flag::Auto).unwrap(), file_read(path).unwrap());
    /// ```
    Auto,
    ///Finds an already existing file. Appends new data to an existing file
    ///  # Examples
    /// ```
    ///   let path = "./Folder1/NewFolder1/file_new.txt";
    ///   
    ///   assert_eq!(file_write(path, "ok", Flag::Old).unwrap(), file_read(path).unwrap());
    /// ```
    Old,
}
/// The function to create paths/files and write data to files with modes  (look at the flag mode in [Flag](enum.Flag.html))
/// # Examples
/// ```
///  //linux
 ///   let path = "./Folder1/NewFolder1/file_new.txt";
///   assert_eq!(file_write(path, "ok", Flag::Auto).unwrap(), file_read(path).unwrap());
///  //macos
 ///   let path = "./Folder1/NewFolder1/file_new.txt";
///   assert_eq!(file_write(path, "ok", Flag::Auto).unwrap(), file_read(path).unwrap());
///  //windows
 ///   let path = "..\\Folder1\\NewFolder1\\file_new.txt";
///   assert_eq!(file_write(path, "ok", Flag::Auto).unwrap(), file_read(path).unwrap());
/// ```
pub fn file_write(path: &str, text: &str, flag: Flag) -> Result<(), io::Error> {
    match flag {
        Flag::Auto => match get_file(path) {
            Ok(_) => return file_write(path, text, Flag::Old),
            Err(_) => match correct_path(path) {
                Ok(new_path) => file_write(&new_path, text, Flag::Old),
                Err(err) => match err.kind() {
                    ErrorKind::NotFound => Ok({
                        let mut temp = collect_folder(path);
                        let name = temp.pop().unwrap();
                        let mut xl = collect_folder(&name);
                        let name = xl.pop().unwrap();
                        let name = name.replace(&xl.pop().unwrap(), "");
                        let temp = temp.pop().unwrap();
                        println!("====================");
                        let result = format!("{}{}", temp, name);
                        if let Err(_) = correct_path(&temp) {
                            DirBuilder::new().recursive(true).create(&temp).unwrap();
                            return file_write(&result, text, Flag::New);
                        } else {
                            let temp = correct_path(&temp).unwrap();
                            let result = format!("{}{}", temp, name);
                            file_write(&result, text, Flag::New).unwrap();
                        }
                    }),
                    ErrorKind::PermissionDenied => {
                        panic!("Permission Denied");
                    }
                    _ => panic!("other errors"),
                },
            },
        },
        Flag::New => match File::create(path) {
            Ok(_) => {
                println!("path new :{}", path);
                OpenOptions::new()
                    .write(true)
                    .create(true)
                    .open(path)
                    .unwrap()
                    .write_all(text.as_bytes())
            }
            Err(err) => return Err(err.kind().into()),
        },
        Flag::Old => OpenOptions::new()
            // .write(true)
            .append(true)
            .open(path)
            .unwrap()
            .write_all(text.as_bytes()),
    }
}