#![feature(uniform_paths)]
mod cfg;
mod data;
mod db;
use cfg::Config;
pub use data::{Id, Item};
use db::{Database, HashMapDb, PersistentDatabase};
use failure::Error;
use std::collections::HashMap;
use std::env;
use std::path::{Path, PathBuf};
const CONFIG_PATH: &str = ".skribe";
const SKRIBE_HOME: &str = "SKRIBE_HOME";
#[derive(Debug)]
pub struct Skribe {
items: HashMapDb<Id, Item>,
config: Config,
}
impl Skribe {
pub fn new() -> Skribe {
let mut items = HashMapDb::new();
items.load();
Skribe {
items: items,
config: Config::default(),
}
}
pub fn get(&self, id: &Id) -> Option<&Item> {
self.items.get(id)
}
pub fn get_mut(&mut self, id: &Id) -> Option<&mut Item> {
self.items.get_mut(id)
}
pub fn get_items(&self) -> &HashMap<Id, Item> {
&self.items.get_all()
}
pub fn create_item() -> Item {
Item::default()
}
pub fn save_item(&mut self, item: Item) -> Option<Item> {
self.items.insert(item.id, item)
}
pub fn delete_item(&mut self, id: &Id) -> Option<Item> {
self.items.remove(id)
}
pub fn init() -> Result<Self, Error> {
let config = Config::init(Self::get_config_path())?;
let items: HashMapDb<Id, Item> = HashMapDb::init();
Ok(Self { config, items })
}
fn get_config_path() -> PathBuf {
match env::var(SKRIBE_HOME) {
Ok(path) => PathBuf::from(path),
Err(_) => {
let home = dirs::home_dir().unwrap_or(PathBuf::from("."));
home.join(Path::new(CONFIG_PATH))
}
}
}
pub fn get_home(&self) -> &PathBuf {
&self.config.path
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn crud_item() {
let mut skribe = Skribe::new();
let item = Skribe::create_item();
let base_id = item.id;
let cloned = item.clone();
{
assert!(
skribe.get(&base_id).is_none(),
"There is nothing in the storage at the beginning"
);
skribe.save_item(item);
assert_eq!(
skribe.get(&base_id).unwrap(),
&cloned,
"The new item is saved successfully"
);
}
{
for (id, item) in skribe.get_items() {
assert_eq!(&base_id, id);
assert_eq!(&cloned, item);
}
}
{
{
let mut editable = skribe.get_mut(&base_id).unwrap();
editable.title = String::from("Edited");
}
assert_eq!(
skribe.get(&base_id).unwrap().title,
String::from("Edited"),
"The item was changed successfully"
);
}
{
let another_cloned = skribe.get(&base_id).unwrap().clone();
let deleted = skribe.delete_item(&base_id).unwrap();
assert_eq!(another_cloned, deleted);
assert!(skribe.get(&base_id).is_none());
}
}
}