From 5a98f84063a8600ff3ce568791463bc63a87224a Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Tue, 3 May 2022 20:11:54 -0600 Subject: [PATCH] Added global config directory + Should be platform independent thanks to platform-dirs + All config files in the directory are used + Some optimizations could be made so now all config files are loaded. + clippy + fmt --- Cargo.lock | 92 ++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- README.md | 7 ++-- src/formatter/mod.rs | 94 ++++++++++++++++++++++++++++++++++---------- src/main.rs | 11 +++++- 5 files changed, 179 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e10df1..b4ef379 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "dirs-next" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "formaty" version = "0.1.0" @@ -107,6 +128,7 @@ dependencies = [ "bitvec", "byteorder", "num-bigint", + "platform-dirs", "rust-embed", "serde", "structopt", @@ -129,6 +151,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.3.3" @@ -155,9 +188,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "num-bigint" @@ -195,6 +228,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "platform-dirs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e188d043c1a692985f78b5464853a263f1a27e5bd6322bad3a4078ee3c998a38" +dependencies = [ + "dirs-next", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -243,6 +285,26 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "rust-embed" version = "6.3.0" @@ -375,6 +437,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.5.8" @@ -431,6 +513,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index f27ec7e..faed9d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ toml = "0.5.8" byteorder = "1.4.3" num-bigint = "0.4" rust-embed="6.3.0" -bitvec = "1.0.0" \ No newline at end of file +bitvec = "1.0.0" +platform-dirs = "0.3.0" \ No newline at end of file diff --git a/README.md b/README.md index bed78b5..9c19e63 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,10 @@ FLAGS: -V, --version Prints version information OPTIONS: - -b, --base Base of the input values - -c, --config Path to the format config [env: FORMATY_CONFIG=] - -i, --input_type Input data type [default: array] + -b, --base Base of the input values + -c, --config Path to the format config [env: FORMATY_CONFIG=] + -g, --global_config Path to the global config directory [env: FORMATY_GLOBAL_CONFIG=] + -i, --input_type Input data type [default: array] ARGS: Format to parse data as diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index e8bddb0..ce70573 100644 --- a/src/formatter/mod.rs +++ b/src/formatter/mod.rs @@ -2,14 +2,15 @@ pub mod format; mod printers; use crate::formatter::format::Format; +use platform_dirs::AppDirs; use rust_embed::RustEmbed; use serde::Deserialize; use std::error::Error; use std::fmt::{Display, Formatter}; -use std::fs::File; +use std::fs::{read_dir, File}; use std::io::Read; use std::path::PathBuf; -use std::str; +use std::{fs, str}; #[derive(Debug)] #[allow(clippy::enum_variant_names)] @@ -63,21 +64,17 @@ pub struct FormatConfig { } impl FormatConfig { - pub fn new(config_path: &Option) -> Result { - let mut config_str = String::new(); - - let mut config: FormatConfig = if let Some(config_path) = config_path { - let mut config = File::open(config_path)?; - config.read_to_string(&mut config_str)?; - - toml::from_str(&config_str).map_err(|e| FormatConfigError::TomlError { - file_name: config_path.to_str().unwrap().to_string(), - err: e, - })? - } else { - FormatConfig::default() - }; + fn parse_config_file( + src_file_name: &str, + config_data: &str, + ) -> Result { + toml::from_str(config_data).map_err(|e| FormatConfigError::TomlError { + file_name: src_file_name.to_string(), + err: e, + }) + } + fn get_built_in_config(&mut self) -> Result<(), FormatConfigError> { for format_file_path in BuiltInFormats::iter() { if format_file_path.ends_with("md") { continue; @@ -88,14 +85,69 @@ impl FormatConfig { let config_str = str::from_utf8(&format_file.data).unwrap(); let mut built_in: FormatConfig = - toml::from_str(config_str).map_err(|e| FormatConfigError::TomlError { - file_name: format_file_path.to_string(), - err: e, - })?; + Self::parse_config_file(&format_file_path, config_str)?; - config.formats.append(&mut built_in.formats); + self.formats.append(&mut built_in.formats); } + Ok(()) + } + + fn get_file_config(&mut self, config_path: &Option) -> Result<(), FormatConfigError> { + if let Some(config_path) = config_path { + let mut config_file = File::open(config_path)?; + let mut config_data = String::new(); + config_file.read_to_string(&mut config_data)?; + let mut arg_config = + Self::parse_config_file(config_path.to_str().unwrap(), &config_data)?; + + self.formats.append(&mut arg_config.formats); + } + + Ok(()) + } + + fn parse_directory( + &mut self, + directory_path: &Option, + ) -> Result<(), FormatConfigError> { + if let Some(directory_path) = directory_path { + for path in read_dir(directory_path)? { + let file_name = path?.file_name(); + let config_file_path = directory_path.join(file_name); + + self.get_file_config(&Some(config_file_path))?; + } + } + + Ok(()) + } + + pub fn new( + config_path: &Option, + global_config_path: &Option, + ) -> Result { + let mut config = FormatConfig::default(); + + config.get_built_in_config()?; + + config.get_file_config(config_path)?; + + let global_dir = match global_config_path { + Some(g) => g.clone(), + None => { + let app_dirs = AppDirs::new(Some("formaty"), true).unwrap(); + + if !app_dirs.config_dir.exists() { + fs::create_dir(&app_dirs.config_dir)?; + } + + app_dirs.config_dir + } + }; + + config.parse_directory(&Some(global_dir))?; + Ok(config) } diff --git a/src/main.rs b/src/main.rs index 9f58b65..6b98ac4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,15 @@ pub struct Args { )] config: Option, + #[structopt( + short = "g", + long = "global_config", + env = "FORMATY_GLOBAL_CONFIG", + parse(from_os_str), + help = "Path to the global config directory" + )] + global_config: Option, + #[structopt( help = "Input data type", short = "i", @@ -43,7 +52,7 @@ pub struct Args { fn init() -> Result<(Vec, Format), FormatyError> { let args: Args = Args::from_args(); - let config = FormatConfig::new(&args.config)?; + let config = FormatConfig::new(&args.config, &args.global_config)?; let format = config.get_format(&args.format)?;