1pub mod elaborate {
2 use std::collections::HashMap;
3 use std::fmt::Debug;
4 use std::fs::{self, File};
5 use std::io::{BufReader, Read, Write};
6 use std::path::Path;
7 use serde::{Serialize, de::DeserializeOwned};
8 use serde_json::to_string;
9
10 #[derive(Debug)]
11 pub enum TErrors {
12 FileNotFound,
13 FileError,
14 ReadByteError,
15 StringConvert
16 }
17
18
19 pub trait ToHash {
22 fn to_hash(&self) -> Result<HashMap<String, String>, serde_json::Error>;
23 fn to_hash_opt(&self) -> serde_json::Result<HashMap<String, Option<String>>>;
24 fn to_hash_vec(&self) -> Result<HashMap<String, Vec<String>>, serde_json::Error>;
25 }
26
27 trait ToHashOpt {
28 fn convert_opt(&self) -> HashMap<String, Option<String>>;
29 }
30
31 impl ToHashOpt for HashMap<String, String> {
32 fn convert_opt(&self) -> HashMap<String, Option<String>> {
33 let mut temp_hash: HashMap<String, Option<String>> = HashMap::new();
34
35 self.into_iter().for_each(|(k, v)| {
36 let v: Option<String> = if v.len()>0 {
37 Some(v.clone())
38 } else {
39 None
40 };
41
42 temp_hash.insert(k.clone(), v);
43 });
44
45 temp_hash
46 }
47 }
48
49 pub fn count_val<T: std::fmt::Debug + Eq>(vec: Vec<T>, value: String) -> usize {
52 vec.into_iter().map(|c| format!("{c:?}").trim().to_string()).filter(|v| *v==value.trim().to_string()).collect::<Vec<String>>().len()
53 }
54
55 pub fn read_hash<T: Serialize + DeserializeOwned + Sized + Clone>(hash: HashMap<String, String>)->Result<T, serde_json::Error>{
57 let convert1: String = serde_json::to_string(&hash).unwrap();
58
59 let convert2: T = serde_json::from_str(&convert1).unwrap();
60
61 Ok(convert2)
62 }
63
64 #[derive(Debug, Serialize)]
65 pub struct Fragment<T: Serialize + DeserializeOwned + Sized + Clone> {
68 pub inner: T,
69 }
70
71 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> ToString for Fragment<T> {
72
73 fn to_string(&self) -> String {
75
76 let Ok(output) = to_string(&self.inner) else {
77 panic!("unable to convert: {self:?}");
78 };
79
80 output
81 }
82 }
83
84 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> ToHash for Fragment<T> {
85 fn to_hash(&self) -> Result<HashMap<String, String>, serde_json::Error> where HashMap<String, String>: Serialize{
87 serde_json::from_str::<HashMap<String, String>>(&self.to_string())
88 }
89 fn to_hash_opt(&self) -> serde_json::Result<HashMap<String, Option<String>>> where HashMap<String, Option<String>>: Serialize{
91 Ok(self.to_hash()?.convert_opt())
92 }
93
94 fn to_hash_vec(&self) -> Result<HashMap<String, Vec<String>>, serde_json::Error> {
96 serde_json::from_str::<HashMap<String, Vec<String>>>(&self.to_string())
97 }
98 }
99
100
101
102 impl<T: Serialize + DeserializeOwned + Sized + Clone + Debug> Fragment<T> {
103 pub fn new(inner: T) -> Self
105 where
106 T: Serialize + DeserializeOwned + Sized + Clone
107 {
108 Self { inner }
109 }
110
111 pub fn read_table(
113 &self,
114 file_path: String,
115 ) -> Result<Fragment<T>, TErrors>
116 {
117 let path: String = format!("./db_files/{}.json", file_path);
118
119 let convert_path: &Path = Path::new(&path);
120
121 if !convert_path.exists() {
122 return Err(TErrors::FileNotFound)
123 }
124
125 let f: File = File::open(convert_path).map_err(|_| TErrors::FileError)?;
126
127 let reader: BufReader<File> = BufReader::new(f);
128
129 let inner_value: T = serde_json::from_reader(reader)
130 .map_err(|_| TErrors::ReadByteError)?;
131
132 let new_value: Fragment<T> = Self::new(inner_value);
133
134 Ok(new_value)
135 }
136
137 pub fn create_table(&self, table_name: String) -> std::io::Result<&Self> {
140
141 let path_root: &String = &String::from("./db_files/");
142
143 if !Path::new(path_root).is_dir() {
144 std::fs::create_dir(path_root).unwrap()
145 }
146
147 if Path::new(&format!("{}{}.json", path_root, table_name)).is_file() {
148 return Ok(self);
149 }
150
151 let string_convert: String = self.to_string();
152
153 let mut src_bytes = string_convert.as_bytes();
154
155 let inner_path: &String = &format!("{path_root}{}", table_name + ".json").to_string();
156
157 let full_path: &Path = &Path::new(inner_path);
158
159 let mut file: File = File::create_new(full_path).unwrap();
160
161 file.write(&mut src_bytes).unwrap();
162
163 Ok(self)
164 }
165
166 pub fn delete_table(&self, table_name: String) -> std::io::Result<()> {
168
169 let path: &String = &format!("./db_files/{}.json", table_name);
170
171 let convert_path: &Path = Path::new(path);
172
173 if convert_path.is_file() {
174 std::fs::remove_file(path)?
175 }
176
177 Ok(())
178 }
179 pub fn delete_table_infer(&self) -> std::io::Result<()> where Fragment<T>: DeserializeOwned{
181 let dir = fs::read_dir("./db_files/").unwrap();
182 for entry in dir.into_iter().filter_map(|f| f.ok()) {
183 let mut context = [0; 10];
184 let mut file: std::fs::File = File::open(entry.path()).unwrap();
185 file.read(&mut context).unwrap();
186 let string_context: String = String::from_utf8_lossy(&context).to_string();
187 if let Ok(_) = serde_json::from_str::<Self>(&string_context) {
188 fs::remove_file(entry.path()).unwrap();
189 } else {
190 continue;
191 }
192 }
193 Ok(())
194 }
195
196 pub fn get_all(&self) -> std::io::Result<Vec<HashMap<String, String>>> {
198 let mut temp_vec: Vec<HashMap<String, String>> = Vec::new();
199 for entry in fs::read_dir("./db_files/")?.into_iter().filter_map(|f| f.ok()) {
200 let obj: Result<Fragment<T>, TErrors> = self.read_table(entry.path().to_string_lossy().to_string());
201 temp_vec.push(obj.unwrap().to_hash().unwrap());
202 }
203 Ok(temp_vec)
204 }
205
206 pub fn get_all_infer(&self) -> std::io::Result<Vec<Fragment<T>>> {
208 let mut temp_vec: Vec<Fragment<T>> = Vec::new();
209
210 for entry in fs::read_dir("./db_files/")?
211 .into_iter()
212 .filter_map(|f| f.ok())
213 {
214 if let Ok(obj) = self.read_table(entry.path().to_string_lossy().to_string()) {
215 temp_vec.push(obj);
216 } else {
217 continue;
218 }
219 }
220
221 Ok(temp_vec)
222 }
223
224 pub fn merge(&self, foreign_table: HashMap<String, String>) -> HashMap<String, String>
226 {
227 let mut hashed_self: HashMap<String, String> = self.to_hash().unwrap();
228 for (key, value) in foreign_table {
229 hashed_self.insert(key, value);
230 }
231 hashed_self
232 }
233
234 pub fn left_join(
236 &self,
237 foreign_table: HashMap<String, Option<String>>,
238 ) -> Result<HashMap<String, String>, serde_json::Error>
239 {
240 let mut self_hashed: HashMap<String, String> = self.to_hash().unwrap();
241
242 let key_vals: Vec<(String, String)> = foreign_table.iter().filter(|(k, _)| self_hashed.contains_key(*k)).map(|(k2, v2)| {
243 let v2: &Option<String> = if v2.is_some() {
244 v2
245 } else {
246 &Some("None".to_string())
247 };
248 return (format!("{}_{}", k2.clone(), count_val(foreign_table.iter().collect(), k2.clone())), v2.clone().unwrap());
249 }).collect();
250
251 key_vals.into_iter().for_each(|(k, v)| {
252 self_hashed.insert(k, v);
253 });
254
255 Ok(self_hashed)
256 }
257
258 pub fn build_where(&self, key: String, value: String) -> Vec<Self> {
260 let mut temp_vec: Vec<Fragment<T>> = Vec::new();
261 for entry in fs::read_dir("./db_files/").unwrap().into_iter().filter_map(|f| f.ok()) {
262 let contents: Fragment<T> = self.read_table(entry.path().to_string_lossy().to_string()).unwrap();
263 let hashed_contents: HashMap<String, String> = contents.to_hash().unwrap();
264 if hashed_contents.contains_key(&key)
265 && hashed_contents.get(&key).unwrap().trim().to_string()
266 == value.trim().to_string()
267 {
268 temp_vec.push(contents)
269 }
270 }
271 temp_vec
272 }
273
274 pub fn update_table(&self, table_name: String, key: String, value: String) -> T{
276 let current_table: Self = self.read_table( table_name).unwrap();
277
278 let mut hashed_table: HashMap<String, String> = current_table.to_hash().unwrap();
279
280 hashed_table.insert(key, value);
281
282 serde_json::from_str::<T>(&serde_json::to_string(&hashed_table).unwrap()).unwrap()
283 }
284
285 pub fn update_table_vec(&self, table_name: String, key: String, value: Vec<String>) -> T {
287 let current_table: Self = self.read_table( table_name).unwrap();
288
289 let mut hashed_table: HashMap<String, Vec<String>> = current_table.to_hash_vec().unwrap();
290
291 hashed_table.insert(key, value);
292
293 serde_json::from_str::<T>(&serde_json::to_string(&hashed_table).unwrap()).unwrap()
294 }
295 }
296}