1pub mod elaborate {
2 use serde::{Serialize, de::DeserializeOwned};
3 use serde_json::to_string;
4 use std::{
5 collections::HashMap,
6 fmt::Debug,
7 fs::{self, DirEntry, File},
8 io::{BufReader, Read, Write},
9 path::Path,
10 };
11
12 #[derive(Debug)]
13 pub enum TErrors {
15 FileNotFound,
17 FileError,
19 DirError,
21 ReadByteError,
23 WriteByteError,
25 StringConvert,
27 HashConvert,
29 DeleteError,
31 }
32
33 pub trait ToHash {
36 fn to_hash(&self) -> Result<HashMap<String, String>, TErrors>;
37 fn to_hash_opt(&self) -> Result<HashMap<String, Option<String>>, TErrors>;
38 fn to_hash_vec(&self) -> Result<HashMap<String, Vec<String>>, TErrors>;
39 }
40
41 trait ToHashOpt {
44 fn convert_opt(&self) -> HashMap<String, Option<String>>;
45 }
46
47 impl ToHashOpt for HashMap<String, String> {
48 fn convert_opt(&self) -> HashMap<String, Option<String>> {
49 let mut temp_hash: HashMap<String, Option<String>> = HashMap::new();
50
51 self.into_iter().for_each(|(k, v)| {
52 let v: Option<String> = if v.len() > 0 { Some(v.clone()) } else { None };
53
54 temp_hash.insert(k.clone(), v);
55 });
56
57 temp_hash
58 }
59 }
60
61 pub fn count_val<T: std::fmt::Debug + Eq>(vec: Vec<T>, value: String) -> usize {
64 vec.into_iter()
65 .map(|c| format!("{c:?}").trim().to_string())
66 .filter(|v| *v == value.trim().to_string())
67 .collect::<Vec<String>>()
68 .len()
69 }
70
71 pub fn read_hash<T: Serialize + DeserializeOwned + Sized + Clone>(
73 hash: HashMap<String, String>,
74 ) -> Result<T, TErrors> {
75 let Ok(convert1) = serde_json::to_string(&hash) else {
76 return Err(TErrors::StringConvert);
77 };
78
79 let Ok(convert2) = serde_json::from_str(&convert1) else {
80 return Err(TErrors::StringConvert);
81 };
82
83 Ok(convert2)
84 }
85
86 #[derive(Debug, Serialize)]
87 pub struct Fragment<T: Serialize + DeserializeOwned + Sized + Clone> {
90 pub inner: T,
91 }
92
93 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> ToString for Fragment<T> {
94 fn to_string(&self) -> String {
96 let Ok(output) = to_string(&self.inner) else {
97 panic!("unable to convert: {self:?}");
98 };
99
100 output
101 }
102 }
103
104 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> ToHash for Fragment<T> {
105 fn to_hash(&self) -> Result<HashMap<String, String>, TErrors>
107 where
108 HashMap<String, String>: Serialize,
109 {
110 let Ok(output) = serde_json::from_str::<HashMap<String, String>>(&self.to_string())
111 else {
112 return Err(TErrors::StringConvert);
113 };
114
115 Ok(output)
116 }
117 fn to_hash_opt(&self) -> Result<HashMap<String, Option<String>>, TErrors>
119 where
120 HashMap<String, Option<String>>: Serialize,
121 {
122 let Ok(output) = self.to_hash() else {
123 return Err(TErrors::HashConvert);
124 };
125
126 Ok(output.convert_opt())
127 }
128
129 fn to_hash_vec(&self) -> Result<HashMap<String, Vec<String>>, TErrors> {
131 let Ok(output) =
132 serde_json::from_str::<HashMap<String, Vec<String>>>(&self.to_string())
133 else {
134 return Err(TErrors::StringConvert);
135 };
136
137 Ok(output)
138 }
139 }
140
141 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> Fragment<T> {
142 pub fn new(inner: T) -> Self
144 where
145 T: Serialize + DeserializeOwned + Sized + Clone,
146 {
147 Self { inner }
148 }
149
150 pub fn read_table(&self, file_path: String) -> Result<Fragment<T>, TErrors> {
152 let path: String = format!("./db_files/{}.json", file_path);
153
154 let convert_path: &Path = Path::new(&path);
155
156 if !convert_path.exists() {
157 return Err(TErrors::FileNotFound);
158 }
159
160 let Ok(f) = File::open(convert_path) else {
161 return Err(TErrors::FileError);
162 };
163
164 let reader: BufReader<File> = BufReader::new(f);
165
166 let Ok(inner_value) = serde_json::from_reader(reader) else {
167 return Err(TErrors::ReadByteError);
168 };
169
170 let new_value: Fragment<T> = Self::new(inner_value);
171
172 Ok(new_value)
173 }
174
175 pub fn create_table(&self, table_name: String) -> Result<&Self, TErrors> {
178 let path_root: &String = &String::from("./db_files/");
179
180 if !Path::new(path_root).is_dir() {
181 std::fs::create_dir(path_root).map_err(|_| {
182 return TErrors::DirError;
183 })?;
184 }
185
186 if Path::new(&format!("{}{}.json", path_root, table_name)).is_file() {
187 return Ok(self);
188 }
189
190 let string_convert: String = self.to_string();
191
192 let mut src_bytes = string_convert.as_bytes();
193
194 let inner_path: &String = &format!("{path_root}{}", table_name + ".json").to_string();
195
196 let full_path: &Path = &Path::new(inner_path);
197
198 let Ok(mut file) = File::create_new(full_path) else {
199 return Err(TErrors::FileError);
200 };
201
202 file.write(&mut src_bytes).map_err(|_| {
203 return TErrors::WriteByteError;
204 })?;
205
206 Ok(self)
207 }
208
209 pub fn delete_table(&self, table_name: String) -> std::io::Result<()> {
211 let path: &String = &format!("./db_files/{}.json", table_name);
212
213 let convert_path: &Path = Path::new(path);
214
215 if convert_path.is_file() {
216 std::fs::remove_file(path)?
217 }
218
219 Ok(())
220 }
221 pub fn delete_table_infer(&self) -> Result<(), TErrors>
223 where
224 Fragment<T>: DeserializeOwned,
225 {
226 let Ok(dir) = fs::read_dir("./db_files/") else {
227 return Err(TErrors::DirError);
228 };
229 for entry in dir.into_iter().filter_map(|f| f.ok()) {
230 let mut context = [0; 10];
231 let Ok(mut file) = File::open(entry.path()) else {
232 return Err(TErrors::FileError);
233 };
234 file.read(&mut context).map_err(|_| {
235 return TErrors::ReadByteError;
236 })?;
237 let string_context: String = String::from_utf8_lossy(&context).to_string();
238 if let Ok(_) = serde_json::from_str::<Self>(&string_context) {
239 fs::remove_file(entry.path()).map_err(|_| {
240 return TErrors::DeleteError;
241 })?;
242 } else {
243 continue;
244 }
245 }
246 Ok(())
247 }
248
249 pub fn get_all(&self) -> Result<Vec<HashMap<String, String>>, TErrors> {
251 let mut temp_vec: Vec<HashMap<String, String>> = Vec::new();
252 for entry in fs::read_dir("./db_files/")
253 .map_err(|_| {
254 return TErrors::DirError;
255 })?
256 .into_iter()
257 .filter_map(|f| f.ok())
258 .collect::<Vec<DirEntry>>()
259 {
260 let Ok(obj) = self.read_table(entry.path().to_string_lossy().to_string()) else {
261 return Err(TErrors::ReadByteError);
262 };
263
264 let Ok(obj_hash) = obj.to_hash() else {
265 return Err(TErrors::HashConvert);
266 };
267 temp_vec.push(obj_hash);
268 }
269 Ok(temp_vec)
270 }
271
272 pub fn get_all_infer(&self) -> std::io::Result<Vec<Fragment<T>>> {
274 let mut temp_vec: Vec<Fragment<T>> = Vec::new();
275
276 for entry in fs::read_dir("./db_files/")?
277 .into_iter()
278 .filter_map(|f| f.ok())
279 {
280 if let Ok(obj) = self.read_table(entry.path().to_string_lossy().to_string()) {
281 temp_vec.push(obj);
282 } else {
283 continue;
284 }
285 }
286
287 Ok(temp_vec)
288 }
289
290 pub fn merge(
292 &self,
293 foreign_table: HashMap<String, String>,
294 ) -> Result<HashMap<String, String>, TErrors> {
295 let Ok(mut hashed_self) = self.to_hash() else {
296 return Err(TErrors::HashConvert);
297 };
298 for (key, value) in foreign_table {
299 hashed_self.insert(key, value);
300 }
301
302 Ok(hashed_self)
303 }
304
305 pub fn left_join(
307 &self,
308 foreign_table: HashMap<String, Option<String>>,
309 ) -> Result<HashMap<String, String>, TErrors> {
310 let Ok(mut self_hashed) = self.to_hash() else {
311 return Err(TErrors::HashConvert);
312 };
313
314 let key_vals: Vec<(String, String)> = foreign_table
315 .iter()
316 .filter(|(k, _)| self_hashed.contains_key(*k))
317 .map(|(k2, v2)| {
318 let v2: &Option<String> = if v2.is_some() {
319 v2
320 } else {
321 &Some("None".to_string())
322 };
323 return (
324 format!(
325 "{}_{}",
326 k2.clone(),
327 count_val(foreign_table.iter().collect(), k2.clone())
328 ),
329 v2.clone().unwrap_or("".to_string()),
330 );
331 })
332 .collect();
333
334 key_vals.into_iter().for_each(|(k, v)| {
335 self_hashed.insert(k, v);
336 });
337
338 Ok(self_hashed)
339 }
340
341 pub fn build_where(&self, key: String, value: String) -> Result<Vec<Self>, TErrors> {
343 let mut temp_vec: Vec<Fragment<T>> = Vec::new();
344 for entry in fs::read_dir("./db_files/")
345 .map_err(|_| {
346 return TErrors::DirError;
347 })?
348 .into_iter()
349 .filter_map(|f| f.ok())
350 {
351 let Ok(contents) = self.read_table(entry.path().to_string_lossy().to_string())
352 else {
353 return Err(TErrors::ReadByteError);
354 };
355 let Ok(hashed_contents) = contents.to_hash() else {
356 return Err(TErrors::HashConvert);
357 };
358 if hashed_contents.contains_key(&key)
359 && hashed_contents
360 .get(&key)
361 .unwrap_or(&"".to_string())
362 .trim()
363 .to_string()
364 == value.trim().to_string()
365 {
366 temp_vec.push(contents)
367 }
368 }
369 Ok(temp_vec)
370 }
371
372 pub fn update_table(
374 &self,
375 table_name: String,
376 key: String,
377 value: String,
378 ) -> Result<T, TErrors> {
379 let Ok(current_table) = self.read_table(table_name) else {
380 return Err(TErrors::FileError);
381 };
382
383 let Ok(mut hashed_table) = current_table.to_hash() else {
384 return Err(TErrors::HashConvert);
385 };
386
387 hashed_table.insert(key, value);
388
389 let Ok(hash_to_string) = &serde_json::to_string(&hashed_table) else {
390 return Err(TErrors::StringConvert);
391 };
392
393 let Ok(output) = serde_json::from_str::<T>(hash_to_string) else {
394 return Err(TErrors::StringConvert);
395 };
396
397 Ok(output)
398 }
399
400 pub fn update_table_vec(
402 &self,
403 table_name: String,
404 key: String,
405 value: Vec<String>,
406 ) -> Result<T, TErrors> {
407 let Ok(current_table) = self.read_table(table_name) else {
408 return Err(TErrors::FileError);
409 };
410
411 let Ok(mut hashed_table) = current_table.to_hash_vec() else {
412 return Err(TErrors::HashConvert);
413 };
414
415 hashed_table.insert(key, value);
416
417 let Ok(hash_to_string) = &serde_json::to_string(&hashed_table) else {
418 return Err(TErrors::HashConvert);
419 };
420
421 let Ok(output) = serde_json::from_str::<T>(hash_to_string) else {
422 return Err(TErrors::StringConvert);
423 };
424
425 Ok(output)
426 }
427 }
428}