|
|
|
use std::fs::{File, OpenOptions};
|
|
|
|
use std::io::{Read, Write, Error};
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use rocket::request::FromForm;
|
|
|
|
use crate::store::model::Model;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
pub mod model;
|
|
|
|
pub mod form;
|
|
|
|
|
|
|
|
/// Store instance
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Store {
|
|
|
|
path : PathBuf,
|
|
|
|
pub model: Model,
|
|
|
|
pub items : HashMap<usize, serde_json::Value>,
|
|
|
|
pub index : Indexes,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Indexes loaded from the indexes file
|
|
|
|
#[derive(Serialize,Deserialize,Debug,Default)]
|
|
|
|
pub struct Indexes {
|
|
|
|
pub free_enums : HashMap<String, Vec<String>>,
|
|
|
|
pub free_tags : HashMap<String, Vec<String>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Struct loaded from the repositroy config file
|
|
|
|
#[derive(Deserialize,Debug)]
|
|
|
|
struct RepositoryConfig {
|
|
|
|
pub model : Model,
|
|
|
|
}
|
|
|
|
|
|
|
|
const REPO_CONFIG_FILE : &'static str = "repository.yaml";
|
|
|
|
const REPO_DATA_FILE : &'static str = "data.json";
|
|
|
|
const REPO_INDEX_FILE : &'static str = "index.json";
|
|
|
|
|
|
|
|
impl Store {
|
|
|
|
pub fn new(path: impl AsRef<Path>) -> Self {
|
|
|
|
let file = load_file(path.as_ref().join(REPO_CONFIG_FILE));
|
|
|
|
|
|
|
|
let repository_config : RepositoryConfig = serde_yaml::from_str(&file)
|
|
|
|
.expect("Error parsing repository config file.");
|
|
|
|
|
|
|
|
let items = load_file_or(path.as_ref().join(REPO_DATA_FILE), "{}");
|
|
|
|
let indexes = load_file_or(path.as_ref().join(REPO_INDEX_FILE), "{}");
|
|
|
|
|
|
|
|
Store {
|
|
|
|
path: path.as_ref().into(),
|
|
|
|
model: repository_config.model,
|
|
|
|
items: serde_json::from_str(&items).expect("Error parsing data file."),
|
|
|
|
index: serde_json::from_str(&indexes).unwrap_or_default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn persist(&self) {
|
|
|
|
let mut file = OpenOptions::new()
|
|
|
|
.write(true)
|
|
|
|
.create(true)
|
|
|
|
.truncate(true)
|
|
|
|
.open(self.path.join(REPO_DATA_FILE))
|
|
|
|
.expect("Error opening data file for writing.");
|
|
|
|
|
|
|
|
let serialized = serde_json::to_string(&self.items).expect("Error serialize.");
|
|
|
|
file.write(serialized.as_bytes()).expect("Error write data file");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn load_file(path: impl AsRef<Path>) -> String {
|
|
|
|
let mut file= File::open(&path).expect(&format!("Error opening file {}", path.as_ref().display()));
|
|
|
|
|
|
|
|
let mut buf = String::new();
|
|
|
|
file.read_to_string(&mut buf).expect(&format!("Error reading file {}", path.as_ref().display()));
|
|
|
|
buf
|
|
|
|
}
|
|
|
|
|
|
|
|
fn load_file_or(file : impl AsRef<Path>, def : impl Into<String>) -> String {
|
|
|
|
let mut file = match File::open(file) {
|
|
|
|
Ok(file) => file,
|
|
|
|
Err(_) => return def.into()
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut buf = String::new();
|
|
|
|
if file.read_to_string(&mut buf).is_err() {
|
|
|
|
return def.into();
|
|
|
|
}
|
|
|
|
|
|
|
|
buf
|
|
|
|
}
|