extern crate serde; extern crate serde_json; extern crate serde_yaml; use serde::{Deserialize, Serialize}; extern crate log; use log::warn; // mod utils; pub mod utils; use utils::SettingsType; #[allow(dead_code)] const RULESET_CURRENT_VERSION: &'static str = "1"; #[derive(Debug, Deserialize, Serialize)] pub struct Settings { #[serde(default = "Settings::get_ruleset_version")] version: String, #[serde(default)] categories: Vec<(String, String)>, #[serde(default)] rules: Vec<(String, String)>, } impl Settings { pub fn new() -> Self { Self { version: Self::get_ruleset_version(), categories: Vec::new(), rules: Vec::new(), } } fn get_ruleset_version() -> String { String::from(RULESET_CURRENT_VERSION) } pub fn export(&self, path: &std::path::Path) -> std::io::Result<()> { let filetype = utils::get_file_type(&path).unwrap(); let content = match filetype { SettingsType::Yaml => match serde_yaml::to_string(&self) { Err(e) => { warn!("Could not serialize settings: {}", e.to_string()); return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, e, )); } Ok(val) => val, }, SettingsType::Json => match serde_json::to_string(&self) { Err(e) => { warn!("Could not serialize settings: {}", e.to_string()); return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, e, )); } Ok(val) => val, }, }; utils::write_file(&path, content) } #[allow(dead_code)] pub fn import(path: &std::path::Path) -> std::io::Result { use SettingsType::*; let display = path.display(); let file_type = utils::get_file_type(&path).unwrap(); let content = match utils::read_file(&path) { Err(e) => { warn!("Could not read file {}: {}", display, e.to_string()); return Err(e); } Ok(content) => content, }; let settings: Settings = match file_type { Yaml => match serde_yaml::from_str(&content) { Err(e) => { warn!("Could not import settings: {}", e.to_string()); return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, e, )); } Ok(val) => val, }, Json => match serde_json::from_str(&content) { Err(e) => { warn!("Could not import settings: {}", e.to_string()); return Err(std::io::Error::new( std::io::ErrorKind::InvalidInput, e, )); } Ok(val) => val, }, }; Ok(settings) } } impl PartialEq for Settings { fn eq(&self, other: &Self) -> bool { self.version == other.version && self.categories == other.categories && self.rules == other.rules } } impl Eq for Settings {} #[test] fn write_settings() { let s = Settings::new(); let path = std::path::Path::new("test.yaml"); let settings = r#"--- version: "1" categories: [] rules: []"#; utils::write_file(&path, serde_yaml::to_string(&s).unwrap()).unwrap(); assert_eq!(settings, utils::read_file(&path).unwrap()); }