use serde::Serialize;
use serde_derive::Deserialize;
use std::error::Error;
use std::fs;
use std::path::Path;
use rich_metadata::RichMetadata;
pub mod rich_metadata;
#[derive(Default, Serialize, Deserialize, PartialOrd, PartialEq, Debug)]
pub struct Config {
pub author: Option<String>,
pub header: Option<String>,
pub footer: Option<String>,
pub extension: Option<String>,
pub rich: Option<RichMetadata>,
}
impl Config {
pub fn new() -> Self {
let mut config = Config::default();
config.rich = Some(RichMetadata::default());
config
}
pub fn set_author(&mut self, author: String) {
self.author = Some(author);
}
pub fn set_header(&mut self, header: Option<String>) {
self.header = header;
}
pub fn set_footer(&mut self, footer: Option<String>) {
self.footer = Option::from(footer);
}
pub fn set_extension(&mut self, extension: Option<String>) {
self.extension = extension;
}
pub fn set_rich(&mut self, rich: RichMetadata) {
self.rich = Some(rich);
}
pub fn create_config_file<P: AsRef<Path>>(&self, config_file: P) -> Result<(), Box<dyn Error>> {
let config_json = serde_json::to_string_pretty(self)?;
fs::write(&config_file, config_json)?;
Ok(())
}
pub fn from_file<P: AsRef<Path>>(config_file: P) -> Result<Self, Box<dyn Error>> {
let config_json = fs::read_to_string(&config_file)?;
let config: Config = serde_json::from_str(&config_json)?;
Ok(config)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Read;
use tempfile::tempdir;
#[test]
fn test_set_author() {
let mut config = Config::new();
config.set_author("test".to_string());
assert_eq!(config.author.unwrap(), "test");
}
#[test]
fn test_set_header() {
let mut config = Config::new();
config.set_header(Some("test".to_string()));
assert_eq!(config.header.unwrap(), "test".to_string());
}
#[test]
fn test_set_footer() {
let mut config = Config::new();
config.set_footer(Some("test".to_string()));
assert_eq!(config.footer.unwrap(), "test".to_string());
}
#[test]
fn test_set_extension() {
let mut config = Config::new();
config.set_extension(Some("test".to_string()));
assert_eq!(config.extension.unwrap(), "test".to_string());
}
#[test]
fn test_create_config_file() {
let dir = tempdir().unwrap();
let config_file = dir.path().join("config.json");
let mut config = Config::new();
config.set_author("test_author".to_string());
config.set_header(Some("test_header".to_string()));
config.set_footer(Some("test_footer".to_string()));
config.set_extension(Some("test_extension".to_string()));
config.create_config_file(&config_file).unwrap();
let mut file = File::open(&config_file).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
assert_eq!(contents, serde_json::to_string_pretty(&config).unwrap());
}
#[test]
fn test_from_file() {
let dir = tempdir().unwrap();
let config_file = dir.path().join("config.json");
let mut config = Config::default();
config.set_author("test_author".to_string());
config.set_header(Some("test_header".to_string()));
config.set_footer(Some("test_footer".to_string()));
config.set_extension(Some("test_extension".to_string()));
config.create_config_file(&config_file).unwrap();
let config_from_file = Config::from_file(&config_file).unwrap();
assert_eq!(config, config_from_file);
}
#[test]
fn test_from_file_with_missing_file() {
let dir = tempdir().unwrap();
let config_file = dir.path().join("config.json");
assert!(Config::from_file(&config_file).is_err());
}
#[test]
fn test_from_file_with_rich() {
let dir = tempdir().unwrap();
let mut config = Config::new();
let config_file = Path::new("config_test.json");
match config.rich {
Some(ref mut rich) => {
rich.extra_metadata.push("test1".to_string());
rich.extra_metadata.push("test2".to_string());
rich.extra_metadata.push("test3".to_string());
},
None => {}
}
config.create_config_file(&config_file).unwrap();
let config_from_file = Config::from_file(&config_file).unwrap();
assert_eq!(config, config_from_file);
}
}