use toml;
use failure::{format_err, Error};
use log::info;
use serde_derive::{Deserialize, Serialize};
use std::{fs::File, io::prelude::*, path::PathBuf};
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub categories: Vec<String>,
pub category_delimiters: Vec<String>,
pub colored_output: bool,
pub default_template: Option<String>,
pub enable_debug: bool,
pub excluded_commit_tags: Vec<String>,
pub enable_footers: bool,
pub show_commit_hash: bool,
pub show_prefix: bool,
pub sort_by: String,
pub template_prefix: String,
}
impl Config {
pub fn new() -> Self {
Config {
categories: Self::get_default_categories(),
category_delimiters: vec!["[".to_owned(), "]".to_owned()],
colored_output: true,
default_template: None,
enable_debug: true,
excluded_commit_tags: vec![],
enable_footers: false,
show_commit_hash: false,
show_prefix: false,
sort_by: "date".to_owned(),
template_prefix: "JIRA-1234".to_owned(),
}
}
fn get_default_categories() -> Vec<String> {
vec![
"Added".to_owned(),
"Changed".to_owned(),
"Fixed".to_owned(),
"Improved".to_owned(),
"Removed".to_owned(),
]
}
pub fn save_default_config(&self, path: &str) -> Result<String, Error> {
let toml_string = toml::to_string(&self).unwrap();
info!("{:?}", toml_string);
let path_buf = self.get_path_with_filename(path);
let path_string = path_buf
.to_str()
.ok_or_else(|| format_err!("Cannot convert path to string"))?;
let mut file = File::create(&path_buf)?;
file.write_all(toml_string.as_bytes())?;
Ok(path_string.to_owned())
}
pub fn load(&mut self, path: &str) -> Result<(), Error> {
let path_buf = self.get_path_with_filename(path);
let mut file = File::open(&path_buf)?;
let mut toml_string = String::new();
file.read_to_string(&mut toml_string)?;
*self = toml::from_str(&toml_string)?;
if self.categories.is_empty() {
self.categories = Self::get_default_categories();
}
Ok(())
}
pub fn is_default_config(&self) -> bool {
*self == Config::new()
}
fn get_path_with_filename(&self, path: &str) -> PathBuf {
let mut path_buf = PathBuf::from(path);
path_buf.push(".gitjournal.toml");
path_buf
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn config_save_and_load_ok() {
let mut config = Config::new();
assert!(config.save_default_config(".").is_ok());
assert!(config.load(".").is_ok());
assert_eq!(config.is_default_config(), true);
}
#[test]
fn config_save_err() {
let config = Config::new();
let res = config.save_default_config("/dev/null");
assert!(res.is_err());
if let Err(e) = res {
println!("{}", e);
}
}
fn load_and_print_failure(path: &str) {
let mut config = Config::new();
let res = config.load(path);
assert!(res.is_err());
if let Err(e) = res {
println!("{}", e);
}
}
#[test]
fn config_load_err() {
load_and_print_failure("/dev/null");
}
#[test]
fn config_load_invalid_1() {
load_and_print_failure("tests/invalid_1.toml");
}
#[test]
fn config_load_invalid_2() {
load_and_print_failure("tests/invalid_2.toml");
}
#[test]
fn config_load_invalid_3() {
load_and_print_failure("tests/invalid_3.toml");
}
}