1static HOBBIT_STORAGE: &str = "/var/tmp/hdb/";
24
25macro_rules! unwrap_or_return {
26 ( $e:expr ) => {
27 match $e {
28 Ok(x) => x,
29 Err(e) => return Err(e.to_string()),
30 }
31 };
32}
33
34macro_rules! some_or_return {
35 ( $e:expr ) => {
36 match $e {
37 Some(x) => x.to_string(),
38 _ => return Err("None".to_string()),
39 }
40 };
41}
42
43fn trim_slash(s: &str) -> String {
47 let trim_len = match s.rfind('/') {
48 None => 0,
49 Some(i) => {
50 if i == s.len() - 1 {
53 i
54 } else {
55 i + 1
57 }
58 }
59 };
60 let trimmed = &s[..trim_len];
61 trimmed.to_string()
62}
63
64pub fn get(table: &str, key: &str) -> Result<String, String> {
66 let path = format!("{}{}", HOBBIT_STORAGE, table);
67 if let Ok(data) = std::fs::read_to_string(&path) {
68 let json: serde_json::Value = unwrap_or_return!(serde_json::from_str(&data));
69 return Ok(some_or_return!(json[key].as_str()));
70 }
71 let error = format!("Error reading table '{}'", table);
72 Err(error)
73}
74
75pub fn set(table: &str, key: &str, value: &str) -> Result<(), String> {
77 let _ = make(table);
79 let path = format!("{}{}", HOBBIT_STORAGE, table);
80 if let Ok(data) = std::fs::read_to_string(&path) {
81 let mut json: serde_json::Value = unwrap_or_return!(serde_json::from_str(&data));
82 json[key] = serde_json::Value::String(value.to_string());
83 return match std::fs::write(&path, json.to_string()) {
84 Ok(_) => Ok(()),
85 Err(e) => Err(e.to_string()),
86 };
87 }
88 let error = format!("Error reading table '{}'", table);
89 Err(error)
90}
91
92pub fn del(table: &str, key: &str) -> Result<(), String> {
94 let path = format!("{}{}", HOBBIT_STORAGE, table);
95 if let Ok(data) = std::fs::read_to_string(&path) {
96 let json: serde_json::Value = unwrap_or_return!(serde_json::from_str(&data));
97 match json {
98 serde_json::Value::Object(mut map) => {
99 map.remove(key);
100 if map.len() == 0 {
102 let _ = std::fs::remove_file(&path);
103 let _ = std::fs::remove_dir(trim_slash(&path));
105 return Ok(());
106 } else {
107 let v: serde_json::Value = map.into();
108 return match std::fs::write(&path, v.to_string()) {
109 Ok(_) => Ok(()),
110 Err(e) => Err(e.to_string()),
111 };
112 }
113 }
114 _ => return Err("Key not found".to_string()),
115 }
116 }
117 let error = format!("Error reading table '{}'", table);
118 Err(error)
119}
120
121fn make(table: &str) -> Result<(), String> {
122 let _ = std::fs::create_dir_all(HOBBIT_STORAGE);
123 let path = format!("{}{}", HOBBIT_STORAGE, table);
124 let _ = std::fs::create_dir_all(trim_slash(&path));
126 if !std::fs::metadata(path.to_string()).is_ok() {
128 let data = serde_json::json!({});
129 match std::fs::write(path.to_string(), data.to_string()) {
130 Ok(_) => return Ok(()),
131 Err(e) => return Err(e.to_string()),
132 }
133 }
134 Ok(())
135}
136
137pub fn map(table: &str) -> Result<serde_json::Map<String, serde_json::Value>, String> {
139 let path = format!("{}{}", HOBBIT_STORAGE, table);
140 if let Ok(data) = std::fs::read_to_string(&path) {
141 let json: serde_json::Value = unwrap_or_return!(serde_json::from_str(&data));
142 match json {
143 serde_json::Value::Object(map) => {
144 return Ok(map);
145 }
146 _ => return Err("Could not parse table as Map".to_string()),
147 }
148 }
149 let error = format!("Error reading table '{}'", table);
150 Err(error)
151}