1pub use struct_to_json_db_macro::auto_json_db;
2use std::fs;
3use std::path::Path;
4use std::io::Write;
5use rand::Rng;
6use magic_crypt::{ new_magic_crypt, MagicCryptTrait};
7pub use paste::paste;
8use lazy_static::lazy_static;
9use std::sync::Mutex;
10
11pub fn read_string_from_txt(filename: &str) -> String {
12 let file_contents = fs::read_to_string(filename).unwrap_or_default();
13 file_contents
14}
15pub fn write_string_to_txt(filename: &str, content: String) {
16
17 let mut file = fs::OpenOptions::new()
18 .write(true)
19 .create(true)
20 .truncate(true)
21 .open(filename)
22 .unwrap();
23 file.write_all(content.as_bytes()).unwrap();
24}
25pub fn write_string_to_txt_encript(filename: &str, content: String,encript:&str) {
26 write_string_to_txt(filename, string_to_crypt(content,encript));
27}
28pub fn read_string_from_txt_encript(filename: &str,encript:&str) -> String {
29 let file_contents = read_string_from_txt(filename);
30 crypt_to_string(file_contents,encript)
31}
32fn string_to_crypt(s: String,encript:&str) -> String {
33 let mc = new_magic_crypt!(encript, 256);
34 mc.encrypt_str_to_base64(s)
35}
36fn crypt_to_string(s: String,encript:&str) -> String {
37 let mc = new_magic_crypt!(encript, 256);
38 match mc.decrypt_base64_to_string(&s) {
39 Ok(r) => r,
40 Err(_) => s,
41 }
42}
43
44pub fn unique_id() -> (u64,u64) {
45 let start = std::time::SystemTime::now();
46 let timestamp = start.duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos() as u64 ;
47 let random_number = rand::thread_rng().gen::<u64>();
48 (random_number,timestamp)
49}
50pub fn make_folder_if_not_exist(path:&str){
51 let path = Path::new(path);
52 if !path.exists() {
53 let _ = fs::create_dir_all(path) ;
54 }
55}
56
57pub fn remove_file_by_path(path: &str) {
58 let path = Path::new(path);
59 if path.exists() {
60 let _ = fs::remove_file(path);
61 }
62}
63pub fn remove_all_files_by_path(path: &str) {
64 let path = Path::new(path);
66 if path.exists() {
67 let _ = fs::remove_dir_all(path);
69 }
70}
71
72use sha2::{Sha256, Digest};
73pub fn string_to_unique_id(input: &str) -> String {
74 let mut hasher = Sha256::new();
76
77 hasher.update(input.as_bytes()); let hash_result = hasher.finalize();
82
83 hash_result
85 .iter()
86 .map(|byte| format!("{:02x}", byte))
87 .collect()
88}
89
90
91#[macro_export]
92macro_rules! json_db_get_by {
93 ($first:ident, $second:ident:$second_type:expr) => {
94 struct_to_json_db::paste! {
95 |all_data:&HashMap<u64, [<$first>]>,byval:[<$second_type>]|->Vec<(u64,[<$first>])>{
96 all_data.iter().filter_map(|(id, obj)| {
97 if obj.[<$second>] == byval {
98 Some((id.clone(), obj.clone()))
99 } else {
100 None
101 }
102 }).collect()
103 }
104 }
105 };
106}
107pub fn set_struct_json_path(path_str:&str){
108 *DB_STRUCT_JSON_PATH.lock().unwrap() = String::from(path_str);
109}
110pub fn get_struct_json_path() -> String {
111 DB_STRUCT_JSON_PATH.lock().unwrap().clone()
112}
113
114lazy_static! {
115 static ref DB_STRUCT_JSON_PATH: Mutex<String> = Mutex::new(String::from("./local_db/"));
116}
117#[macro_export]
118macro_rules! auto_json_db_config {
119 ($path_str:expr) => {
120 use struct_to_json_db::*;
121 use serde::{Deserialize, Serialize};
122 };
123}
124
125#[macro_export]
126macro_rules! auto_json_db_single{
127 ($struct:ident) => {
128 struct_to_json_db::paste! {
129 impl [<$struct>] {
130 pub fn save(&self) {
131 let file_path =get_struct_json_path() + "/" + stringify!($struct) + ".json";
132 let json_data = serde_json::to_string(self).unwrap();
133 write_string_to_txt(&file_path, json_data);
134 }
135 pub fn load()->Self{
136 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
137 let file_contents = read_string_from_txt(&file_path);
138 if file_contents.is_empty() {
139 [<$struct>]::default()
140
141 }else{
142 let r = serde_json::from_str(&file_contents).ok();
143 r.unwrap_or_default()
144 }
145
146 }
147 }
148 }
149 };
150 ($struct:ident, $pass:literal) => {
151 struct_to_json_db::paste! {
152
153 impl [<$struct>] {
154 pub fn save(&self) {
155 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
156 let json_data = serde_json::to_string(self).unwrap();
157 write_string_to_txt_encript(&file_path, json_data,$pass);
158 }
159 pub fn load()->Self{
160 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
161 let file_contents = read_string_from_txt_encript(&file_path,$pass);
162 if file_contents.is_empty() {
163 [<$struct>]::default()
164 }else{
165 let r = serde_json::from_str(&file_contents).ok();
166 r.unwrap_or_default()
167 }
168
169 }
170 }
171
172 }
173 };
174}
175#[macro_export]
176macro_rules! auto_json_db_one_file{
177 ($struct:ident) => {
178 struct_to_json_db::paste! {
179 impl [<$struct>] {
180 pub fn save(&self) {
181 let mut data = Self::load();
182 let is_available = data.iter().any(|i| i == self);
183 if !is_available {
184 data.push(self.clone());
185 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
186 let json_data = serde_json::to_string(&data).unwrap();
187 write_string_to_txt(&file_path, json_data);
188 }
189 }
190 pub fn remove(&self){
191 let mut data = Self::load();
192 let is_available = data.iter().any(|i| i == self);
193 if is_available {
194 data.retain(|i| i != self);
195 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
196 let json_data = serde_json::to_string(&data).unwrap();
197 write_string_to_txt(&file_path, json_data);
198 }
199 }
200 pub fn save_all(data:&Vec<Self>){
201 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
202 let json_data = serde_json::to_string(data).unwrap();
203 write_string_to_txt(&file_path, json_data);
204 }
205 pub fn load()->Vec<Self>{
206 let file_path = get_struct_json_path() + "/" + stringify!($struct) + ".json";
207 let file_contents = read_string_from_txt(&file_path);
208 if file_contents.is_empty() {
209 vec![]
210 }else{
211 let r = serde_json::from_str(&file_contents).ok();
212 r.unwrap_or(vec![])
213 }
214
215 }
216 }
217 }
218 }
219}
220
221#[macro_export]
222macro_rules! json_db_relation {
223 ($first:ident=$field:ident, $second:ident) => {
224 struct_to_json_db::paste! {
225 impl [<$first>] {
226 pub fn [<get_ $field>](&self)->Vec<[<$second>]>{
227 let data = [<$second>]::get_by_ids(&self.[<$field>]);
228 data
229 }
230 pub fn [<set_ $field>](&mut self,v:&Vec<[<$second>]>){
231 self.[<$field>] = v.iter().map(|item| item.idx).collect();
232 self.save();
233 }
234 }
235 }
236 };
237 ($first:ident=$field:ident, $second:ident,"1:1") => {
238 struct_to_json_db::paste! {
239 impl [<$first>] {
240 pub fn [<get_ $field>](&self)->Option<[<$second>]>{
241 let data = [<$second>]::get_by_id(self.[<$field>]);
242 data
243 }
244 pub fn [<set_ $field>](&mut self,v:&[<$second>]){
245 self.[<$field>] = v.idx;
246 self.save();
247 }
248 }
249 }
250 };
251
252}
253
254
255
256#[macro_export]
257macro_rules! mapping_json_struct {
258 (
259 $(#[$meta:meta])*
260 $vis:vis struct $name:ident {
261 $($field_vis:vis $field_name:ident : $field_type:ty),*
262 $(,)?
263 }
264 ) => {
265 paste! {
266 $(#[$meta])*
267
268 $vis struct [<Behalf $name>] {
269 $($field_vis $field_name : $field_type),*
270 }
271
272 impl [<Behalf $name>] {
273 $vis fn to(&self) -> [<$name>] {
275 [<$name>] {
276 $($field_name: self.$field_name.clone()),*
277 }
278 }
279 }
280
281 impl From<$name> for [<Behalf $name>] {
282 fn from(item: $name) -> Self {
283 let now_idx = struct_to_json_db::unique_id();
284 [<Behalf $name>] {
285 idx: now_idx.0^now_idx.1,
286 created_at: now_idx.1,
287 $($field_name: item.$field_name),*
288 }
289 }
290
291 }
292
293 }
294 };
295}