From 8cefe25d62bbd89a3fc14124eb6713c873ff9489 Mon Sep 17 00:00:00 2001 From: Marcello Lamonaca Date: Fri, 8 Nov 2024 12:54:02 +0100 Subject: [PATCH] allow choice of array separator and enumeration --- src/main.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 888f85f..5cd8627 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,8 +31,14 @@ fn main() -> Result<(), Box> { let json: Value = serde_json::from_str(&buffer) .inspect_err(|_| eprintln!("Error: `{input}` does not contain valid JSON"))?; + let options = ParseOptions::new( + args.key_separator, + args.array_separator, + args.enumerate_array, + ); + let mut vars: Vec = vec![]; - JsonParser::parse(&mut vars, "", &json, &args.separator); + JsonParser::parse(&mut vars, "", &json, &options); let environ = vars .iter() @@ -70,25 +76,62 @@ struct Args { output: Option, /// Separator for nested keys - #[arg(short, long, value_name = "STRING", default_value = "__")] - separator: String, + #[arg(short = 's', long, value_name = "STRING", default_value = "__")] + key_separator: String, + + /// Separator for array elements + #[arg(short = 'S', long, value_name = "STRING", default_value = ",")] + array_separator: String, + + /// Separate array elements in multiple environment variables + #[arg(short, long)] + enumerate_array: bool, +} + +#[derive(Debug)] +struct ParseOptions { + key_separator: String, + array_separator: String, + enumerate_array: bool, +} + +impl ParseOptions { + fn new(key_separator: String, array_separator: String, enumerate_array: bool) -> Self { + Self { + key_separator, + array_separator, + enumerate_array, + } + } } struct JsonParser; impl JsonParser { - fn parse(lines: &mut Vec, key: &str, value: &Value, separator: &str) { + fn parse(lines: &mut Vec, key: &str, value: &Value, options: &ParseOptions) { match value { Value::Array(array) => { - for (index, item) in array.iter().enumerate() { - let key = Self::build_key(key, index.to_string().as_str(), separator); - Self::parse(lines, &key, item, separator) + if options.enumerate_array { + for (index, item) in array.iter().enumerate() { + let key = Self::build_key(key, &index.to_string(), &options.key_separator); + Self::parse(lines, &key, item, options) + } + } else { + let value = array + .iter() + .map(ToString::to_string) + .collect::>() + .join(&options.array_separator); + + let item = serde_json::Value::String(value); + + Self::parse(lines, key, &item, options) } } Value::Object(object) => { for (name, value) in object { - let key = Self::build_key(key, name.as_str(), separator); - Self::parse(lines, &key, value, separator) + let key = Self::build_key(key, name.as_str(), &options.key_separator); + Self::parse(lines, &key, value, options) } } _ => lines.push(EnvVar(key.trim().to_owned(), value.clone())),