diff --git a/jaq/src/cli.rs b/jaq/src/cli.rs index 658baa0d..7c627ec8 100644 --- a/jaq/src/cli.rs +++ b/jaq/src/cli.rs @@ -35,6 +35,7 @@ pub struct Cli { // Key-value options pub arg: Vec<(String, String)>, + pub argjson: Vec<(String, String)>, pub slurpfile: Vec<(String, OsString)>, pub rawfile: Vec<(String, OsString)>, @@ -106,6 +107,10 @@ impl Cli { let (name, value) = parse_key_val("--arg", args)?; self.arg.push((name, value.into_string()?)); } + "argjson" => { + let (name, value) = parse_key_val("--argjson", args)?; + self.argjson.push((name, value.into_string()?)); + } "slurpfile" => self.slurpfile.push(parse_key_val("--slurpfile", args)?), "rawfile" => self.rawfile.push(parse_key_val("--rawfile", args)?), diff --git a/jaq/src/help.txt b/jaq/src/help.txt index c6938f72..e75cd7e8 100644 --- a/jaq/src/help.txt +++ b/jaq/src/help.txt @@ -28,6 +28,7 @@ Compilation options: Variable options: --arg Set variable `$A` to string `V` + --argjson Set variable `$A` to JSON value `V` --slurpfile Set variable `$A` to array containing the JSON values in file `F` --rawfile Set variable `$A` to string containing the contents of file `F` --args Collect remaining positional arguments into `$ARGS.positional` diff --git a/jaq/src/main.rs b/jaq/src/main.rs index 5620c304..d0e539dc 100644 --- a/jaq/src/main.rs +++ b/jaq/src/main.rs @@ -134,6 +134,15 @@ fn binds(cli: &Cli) -> Result, Error> { let s = s.to_owned(); Ok((k.to_owned(), Val::Str(s.into()))) }); + let argjson = cli.argjson.iter().map(|(k, s)| { + let s = s.to_owned(); + use hifijson::token::Lex; + let mut lexer = hifijson::SliceLexer::new(s.as_bytes()); + let v = lexer + .exactly_one(Val::parse) + .map_err(|e| Error::Parse(format!("cannot parse {s} as JSON: {e}"))); + Ok::<(std::string::String, Val), Error>((k.to_owned(), v?)) + }); let rawfile = cli.rawfile.iter().map(|(k, path)| { let s = std::fs::read_to_string(path).map_err(|e| Error::Io(Some(format!("{path:?}")), e)); Ok((k.to_owned(), Val::Str(s?.into()))) @@ -146,7 +155,7 @@ fn binds(cli: &Cli) -> Result, Error> { let positional = cli.args.iter().cloned().map(|s| Ok(Val::from(s))); let positional = positional.collect::, Error>>()?; - let var_val = arg.chain(rawfile).chain(slurpfile); + let var_val = arg.chain(rawfile).chain(slurpfile).chain(argjson); let mut var_val = var_val.collect::, Error>>()?; var_val.push(("ARGS".to_string(), args(&positional, &var_val))); diff --git a/jaq/tests/golden.rs b/jaq/tests/golden.rs index 10355efc..40b37446 100644 --- a/jaq/tests/golden.rs +++ b/jaq/tests/golden.rs @@ -43,6 +43,18 @@ test!( "\"yb\"" ); +test!( + argjson, + &["--argjson", "a", "[1,2,3]", "--argjson", "b", r#""abc""#, "$a,$b"], + "0", + r#"[ + 1, + 2, + 3 +] +"abc""# +); + test!( args, &["-c", "--args", "--arg", "x", "y", "$ARGS", "a", "--", "--test", "--"],