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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! file.rs
//! Dieses Modul enthaelt die Definierung der Klasse File, basierend aus den Rohbindungen von c.
//! Unsafe ist verwaschen und im raw zu finden, mit allen anderen Komponenten.
//! Bedenken sie, wenn sie auf raw zugreifen, welches ich extra offen und public gemacht habe, dass sie CString verwenden muessen.
//! Wenn sie wirklich die Komplett Rohen Bindungen von C nutzen wollt, finden sie in raw das submodul depends, dort finden sie die vollen rohen bindungen.
//! Wichtige Notiz:
//! Die Rohe bindungen in raw und in raw::depends sind unsafe und es wird abgeraten, diese direkt aufzurufen, vielmehr sind sie eher als Self Build Komponenten anzusehen.
//! Fuer den Allgemeinen gebrauch wird die Klasse File empfohlen, da sie alles buendelt, getestet und gesichert ist.
//! In der Klasse File werden keine unsafe mehr ausgeloest, sie koennen ganz normal mit strings arbeiten und erhalten alles korrekt wieder.
//! 
//! Beispiel Verwendun
//! 
//! ## Klasse File
//! ```rust
//! use dexalt_lib::file::File;
//! 
//! fn main() {
//!     let mut file = File::new("test.txt", "w");
//!     file.write("Hello, World!");
//!     let mut filen = File::default_read("test.txt") /// Diesmal verwenden wir default_read, heisst, der mode ist auf "r" voreingestellt.
//!     let data = file.read();
//!     println!("{}", data);
//! }
//! ```
//! ---
pub mod raw;

/// # Settings trait
/// 
/// Der Settings Trait wird verwendet, um voreinstellungen zu definieren, es gibt:
/// 1. default_read
/// 2. default_write
/// 
/// ## Implementierung
/// 
/// Aktuell wird Settings so Definiert
/// 
/// ```rust
/// pub trait Settings {
///     fn default_read(&self, filepath: &str) -> Self;
///     fn default_write(&self, filepath: &str) -> Self;
/// }
/// ```
/// 
/// Und so Implementiert
/// 
/// ```rust
/// impl Settings for File {
///     fn default_read(&self, filepath: &str) -> Self {
///         let filepath_c = to_cstring(filepath);
///         let filemode_c = to_cstring("r");
///         let instance_c = raw::DexaltFile::new(filepath_c, filemode_c);
///     }
///     fn default_write(&self, filepath: &str) -> Self {
///         let filepath_c = to_cstring(filepath);
///         let filemode_c = to_cstring("w");
///         let instance_c = raw::DexaltFile::new(filepath_c, filemode_c);
///     }
/// }
/// ```
/// 
/// ---
pub trait Settings {
    fn default_read(&self, filepath: &str) -> Self;
    fn default_write(&self, filepath: &str) -> Self;
}

fn to_cstring(s: &str) -> std::ffi::CString {
    let c_string = std::ffi::CString::new(s).unwrap();
    c_string
}

pub struct File {
    pub filepath: String,
    pub filemode: String,
    pub instance: raw::DexaltFile,
}

impl File {

    pub fn new(filepath: &str, filemode: &str) -> Self {
        let filepath_c = to_cstring(filepath);
        let filemode_c = to_cstring(filemode);

        let instance_c = raw::DexaltFile::new(filepath_c, filemode_c);
        Self {
            filepath: String::from(filepath),
            filemode: String::from(filemode),
            instance: instance_c,
        }
    }

    fn open(&mut self) {
        self.instance.open();
    }

    fn close(&mut self) {
        self.instance.close();
    }

    pub fn write(&mut self, data: &str) {
        let data_c = to_cstring(data);
        self.open();
        self.instance.write(data_c);
        self.close();
    }

    pub fn read(&mut self) -> String {
        self.open();
        let data_c = self.instance.read();
        self.close();
        let string = data_c.to_str().unwrap().to_string();
        string
    }

    pub fn get_filepath(&self) -> String {
        let filepath_c = self.instance.get_filepath();
        let filepath = filepath_c.to_str().unwrap().to_string();
        filepath
    }

    pub fn get_filemode(&self) -> String {
        let filemode_c = self.instance.get_filemode();
        let filemode = filemode_c.to_str().unwrap().to_string();
        filemode
    }

    pub fn get_filesize(&self) -> f32 {
        self.instance.get_filesize()
    }
}

impl Settings for File {
    fn default_read(&self, filepath: &str) -> Self {
        let filepath_c = to_cstring(filepath);
        let filemode_c = to_cstring("r");
        let instance_c = raw::DexaltFile::new(filepath_c, filemode_c);
        Self {
            filepath: String::from(filepath),
            filemode: String::from("r"),
            instance: instance_c,
        }
    }
    fn default_write(&self, filepath: &str) -> Self {
        let filepath_c = to_cstring(filepath);
        let filemode_c = to_cstring("w");
        let instance_c = raw::DexaltFile::new(filepath_c, filemode_c);
        Self {
            filepath: String::from(filepath),
            filemode: String::from("w"),
            instance: instance_c,
        }
    }
}