diff options
author | Bryan Newbold <bnewbold@robocracy.org> | 2022-10-27 23:03:28 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2022-10-27 23:03:28 -0700 |
commit | 7ba5eec5a87c14f8cfe944131d6fb7229648d81f (patch) | |
tree | f6def4f470ddd8242f7aa37f1c485a9b588b9038 /adenosine-cli/src/lib.rs | |
parent | dc24074377875b7f500b20e4f6088930f2eef4ea (diff) | |
download | adenosine-7ba5eec5a87c14f8cfe944131d6fb7229648d81f.tar.gz adenosine-7ba5eec5a87c14f8cfe944131d6fb7229648d81f.zip |
cli: parse fields as body or query params from args
Diffstat (limited to 'adenosine-cli/src/lib.rs')
-rw-r--r-- | adenosine-cli/src/lib.rs | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/adenosine-cli/src/lib.rs b/adenosine-cli/src/lib.rs index 8f462da..6d953ca 100644 --- a/adenosine-cli/src/lib.rs +++ b/adenosine-cli/src/lib.rs @@ -1,5 +1,7 @@ use anyhow::anyhow; pub use anyhow::Result; +use lazy_static::lazy_static; +use regex::Regex; use reqwest::header; use serde_json::Value; use std::collections::HashMap; @@ -178,5 +180,63 @@ fn test_parse_jwt() { assert!(parse_did_from_jwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9").is_err()); } -// TODO: parse at-uri -// at://did:plc:ltk4reuh7rkoy2frnueetpb5/app.bsky.follow/3jg23pbmlhc2a +/// Represents fields/content specified on the command line. +/// +/// Sort of like HTTPie. Query parameters are '==', body values (JSON) are '='. Only single-level +/// body values are allowed currently, not JSON Pointer assignment. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum ArgField { + Query(String, serde_json::Value), + Body(String, serde_json::Value), +} + +impl FromStr for ArgField { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + lazy_static! { + static ref FIELD_RE: Regex = Regex::new(r"^([a-zA-Z_]+)=(=?)(.*)$").unwrap(); + } + if let Some(captures) = FIELD_RE.captures(s) { + let key = captures[1].to_string(); + let val = Value::from_str(&captures[3])?; + if captures.get(2).is_some() { + Ok(ArgField::Query(key, val)) + } else { + Ok(ArgField::Body(key, val)) + } + } else { + Err(anyhow!("could not parse as a field assignment: {}", s)) + } + } +} + +// TODO: what should type signature actually be here... +pub fn update_params_from_fields(fields: &[ArgField], params: &mut HashMap<String, String>) { + for f in fields.iter() { + if let ArgField::Query(ref k, ref v) = f { + params.insert(k.to_string(), v.to_string()); + } + } +} + +pub fn update_value_from_fields(fields: Vec<ArgField>, value: &mut Value) { + if let Value::Object(map) = value { + for f in fields.into_iter() { + if let ArgField::Body(k, v) = f { + map.insert(k, v); + } + } + } +} + +/// Consumes the entire Vec of fields passed in +pub fn value_from_fields(fields: Vec<ArgField>) -> Value { + let mut map: HashMap<String, Value> = HashMap::new(); + for f in fields.into_iter() { + if let ArgField::Body(k, v) = f { + map.insert(k, v); + } + } + Value::Object(serde_json::map::Map::from_iter(map.into_iter())) +} |