1use core::panic;
2use std::{
3 fmt,
4 path::Path,
5 collections::HashMap,
6 fs::{
7 File,
8 read_to_string
9 },
10 io::{
11 Result,
12 Write
13 },
14};
15
16use serde_json::Value as JSONValue;
17
18pub type Value = JSONValue;
19pub type JSON = HashMap<String, JSONValue>;
20
21pub struct Storage {
22 pub path: String,
23 pub content: JSON
24}
25
26fn write_json_to_file(filepath: String, json: JSON) {
27 let path = Path::new(&filepath);
28
29 let data = match serde_json::to_string(&json) {
30 Ok(data) => data,
31 Err(err) => panic!("Couldn't serialize JSON: {}", err)
32 };
33
34 let mut file = match File::create(&filepath) {
35 Ok(file) => file,
36 Err(err) => panic!("Couldn't read file: ({}) {}", path.display(), err)
37 };
38
39 match file.write_all(data.as_bytes()) {
40 Err(err) => panic!("Error writing file: ({}) {}", path.display(), err),
41 Ok(_) => ()
42 }
43}
44
45impl Storage {
46 pub fn new(filename: &str) -> Storage {
47 let path = Path::new(filename);
48
49 if !path.exists() {
50 File::create(path)
51 .expect("An error is occurred while trying to open the configuration file.");
52
53 write_json_to_file(filename.to_string(), JSON::new());
54 }
55
56 Storage {
57 path: String::from(filename),
58 content: JSON::new()
59 }
60 }
61
62 pub fn update_file(&self) -> Result<()> {
63 let path = Path::new(&self.path);
64
65 let data = serde_json::to_string(&self.content)?;
66 let mut file = File::create(&path)?;
67 file.write_all(data.as_bytes())?;
68
69 Ok(())
70 }
71
72 pub fn pull(&mut self) -> Result<()> {
73 let string_content = read_to_string(Path::new(&self.path))?;
74 let data : JSON = serde_json::from_str(&string_content)?;
75 self.content = data;
76
77 Ok(())
78 }
79
80 pub fn get(&self, key: String) -> std::result::Result<Value, KeyNotFoundError> {
81 let data = &self.content;
82
83 if !data.contains_key(&key) {
84 return Err(KeyNotFoundError);
85 }
86
87 Ok(data[&key].clone())
88 }
89
90 pub fn put(&mut self, key: String, value: JSONValue) -> Result<()> {
91 &self.content.insert(key, value);
92 self.update_file()?;
93
94 Ok(())
95 }
96}
97
98#[derive(Debug, Clone)]
100pub struct KeyNotFoundError;
101
102impl fmt::Display for KeyNotFoundError {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "Invalid key.")
105 }
106}