1use serde::{Deserialize, Serialize};
2use std::{env, fs, path::Path};
3
4mod test;
5
6pub struct JsonDB {
17 path: String,
18}
19
20impl JsonDB {
21 pub fn init(path: &str) -> Result<JsonDB, Box<dyn std::error::Error>> {
29 let db_path = format!("{}/.JsonDB/{}/", env::var("HOME")?, path);
30 if !Path::new(&*format!("{}/.JsonDB/{}/", env::var("HOME")?, path)).is_dir() {
31 fs::create_dir_all(format!("{}/.JsonDB/{}/", env::var("HOME")?, path))?;
32 }
33 Ok(JsonDB { path: db_path })
34 }
35
36 pub fn create_collection<S>(
44 self,
45 collection_path: S,
46 ) -> Result<JsonDB, Box<dyn std::error::Error>>
47 where
48 S: Into<String>,
49 {
50 fs::create_dir(format!("{}/{}", self.path, collection_path.into()))?;
51 Ok(self)
52 }
53
54 pub fn write<J, S>(
62 self,
63 collection_path: S,
64 document: S,
65 data: J,
66 ) -> Result<JsonDB, Box<dyn std::error::Error>>
67 where
68 J: Serialize,
69 S: Into<String>,
70 {
71 let serialized = serde_json::to_string(&data)?;
72 fs::write(
73 format!(
74 "{}/{}/{}.data.json",
75 self.path,
76 collection_path.into(),
77 document.into()
78 ),
79 serialized,
80 )?;
81 Ok(self)
82 }
83
84 pub fn read<D, S>(
91 self,
92 collection_path: S,
93 document: S,
94 ) -> Result<D, Box<dyn std::error::Error>>
95 where
96 for<'a> D: Deserialize<'a>,
97 S: Into<String>,
98 {
99 let data = serde_json::from_str::<D>(
100 fs::read_to_string(format!(
101 "{}/{}/{}.data.json",
102 self.path,
103 collection_path.into(),
104 document.into()
105 ))?
106 .as_str(),
107 )?;
108 Ok(data)
109 }
110
111 pub fn delete<S>(
119 self,
120 collection_path: S,
121 document: S,
122 ) -> Result<JsonDB, Box<dyn std::error::Error>>
123 where
124 S: Into<String>,
125 {
126 fs::remove_file(format!(
127 "{}/{}/{}.data.json",
128 self.path,
129 collection_path.into(),
130 document.into()
131 ))?;
132 Ok(self)
133 }
134
135 pub fn list<S>(self, collection_path: S) -> Result<Vec<String>, Box<dyn std::error::Error>>
143 where
144 S: Into<String>,
145 {
146 let mut list: Vec<String> = Vec::new();
147 for file in fs::read_dir(format!("{}/{}/", self.path, collection_path.into()))? {
148 let mut value = file?.file_name().into_string().unwrap();
149 let len = value.chars().count() - 10;
150 let string = String::from(value.drain(0..len).as_str());
151
152 list.push(string);
153 }
154 Ok(list)
155 }
156}