simple-storage 0.0.2

Super simple key-value storage.
Documentation
use core::panic;
use std::{
  fmt,
  path::Path,
  collections::HashMap,
  fs::{
    File,
    read_to_string
  },
  io::{
    Result,
    Write
  },
};

use serde_json::Value as JSONValue;

pub type Value = JSONValue;
pub type JSON = HashMap<String, JSONValue>;

pub struct Storage {
  pub path: String,
  pub content: JSON
}

fn write_json_to_file(filepath: String, json: JSON) {
  let path = Path::new(&filepath);

  let data = match serde_json::to_string(&json) {
    Ok(data) => data,
    Err(err) => panic!("Couldn't serialize JSON: {}", err)
  };

  let mut file = match File::create(&filepath) {
    Ok(file) => file,
    Err(err) => panic!("Couldn't read file: ({}) {}", path.display(), err)
  };

  match file.write_all(data.as_bytes()) {
    Err(err) => panic!("Error writing file: ({}) {}", path.display(), err),
    Ok(_) => ()
  }
}

impl Storage {
  pub fn new(filename: &str) -> Storage {
    let path = Path::new(filename);

    if !path.exists() {
      File::create(path)
        .expect("An error is occurred while trying to open the configuration file.");

      write_json_to_file(filename.to_string(), JSON::new());
    }

    Storage {
      path: String::from(filename),
      content: JSON::new()
    }
  }

  pub fn update_file(&self) -> Result<()> {
    let path = Path::new(&self.path);

    let data = serde_json::to_string(&self.content)?;
    let mut file = File::create(&path)?;
    file.write_all(data.as_bytes())?;

    Ok(())
  }

  pub fn pull(&mut self) -> Result<()> {
    let string_content = read_to_string(Path::new(&self.path))?;
    let data : JSON = serde_json::from_str(&string_content)?;
    self.content = data;

    Ok(())
  }

  pub fn get(&self, key: String) -> std::result::Result<Value, KeyNotFoundError> {
    let data = &self.content;

    if !data.contains_key(&key) {
      return Err(KeyNotFoundError);
    }

    Ok(data[&key].clone())
  }

  pub fn put(&mut self, key: String, value: JSONValue) -> Result<()> {
    &self.content.insert(key, value);
    self.update_file()?;

    Ok(())
  }
}

// Error when a key cannot be found.
#[derive(Debug, Clone)]
pub struct KeyNotFoundError;

impl fmt::Display for KeyNotFoundError {
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    write!(f, "Invalid key.")
  }
}