nunc 0.2.0

WIP: time tracking application
Documentation
use std::fs::{
	create_dir,
	read_to_string
};
use std::path::{
	Path,
	PathBuf
};

use serde::{
	Deserialize,
	Serialize
};

use crate::cache::Cache;
use crate::error::Result;

pub const DEFAULT_CONFIG_PATH: &str = "nunc/config.tml";
pub const DEFAULT_CACHE_PATH: &str = "nunc/cache.db";

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Config {
	pub db_path: PathBuf,
	pub use_cache: Option<bool>,
	pub cache_path: Option<PathBuf>
}

impl Config {
	pub fn default_path() -> PathBuf {
		let mut dir = dirs::config_dir()
			.expect("failed to get XDG config directory");
		dir.push(DEFAULT_CONFIG_PATH);
		dir
	}
	pub fn read(config_file: &Path) -> Result<Self> {
		let content = read_to_string(config_file)?;
		Ok(toml::from_str(&content)?)
	}

	/// Open or create the cache datebase, on disk or in memory
	///
	/// Additionally creates the cache directory (i.e. `~/.cache/nunc`) if it doesn't exist and is required.
	/// Will not create the cache database's parent directory if `cache_path` is set explicitly.
	pub fn open_cache(&self) -> Result<Cache> {
		let cache = match (self.use_cache, &self.cache_path) {
			(Some(true), Some(path)) if path.exists() => Cache::open(path)?,
			(Some(true), Some(path)) => Cache::init(path)?,
			(Some(true), None) => {
				let mut path = dirs::cache_dir()
					.expect("failed to get XDG cache directory");
				path.push(DEFAULT_CACHE_PATH);
				if !path.parent().unwrap().exists() {
					create_dir(&path)?;
				}
				if path.exists() {Cache::open(&path)?}
				else {Cache::init(&path)?}
			},
			(Some(false) | None, _) => Cache::create_in_memory()?
		};
		Ok(cache)
	}
}