simple_storage/
lib.rs

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// Error when a key cannot be found.
99#[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}