use common_failures::Result;
use failure::{format_err, Error};
use log::warn;
use serde_json::Value;
use std::str::FromStr;
#[derive(Debug)]
pub struct ExecutionInput {
pub name: String,
pub value: Value,
}
impl FromStr for ExecutionInput {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
let split = s.splitn(2, '=').collect::<Vec<&str>>();
if split.len() != 2 {
return Err(format_err!("input {:?} must have form \"key=value\"", s,));
}
let name = split[0].to_owned();
let value = match serde_json::from_str(split[1]) {
Ok(value) => value,
Err(err) => {
warn!(
"could not parse input {:?} as JSON (treating as string): {}",
s, err,
);
Value::String(split[1].to_owned())
}
};
Ok(ExecutionInput { name, value })
}
}
#[test]
fn parses_json_values() {
let examples = &[
("x=null", Value::Null),
("x=true", Value::Bool(true)),
("x=false", Value::Bool(false)),
("x=0", Value::Number(0.into())),
("x=[true]", Value::Array(vec![Value::Bool(true)])),
("x=\"hi\"", Value::String("hi".to_owned())),
];
for (input, expected) in examples {
let parsed = input.parse::<ExecutionInput>().unwrap();
assert_eq!(&parsed.value, expected);
}
}
#[test]
fn defaults_to_string_values() {
let parsed = "x=hi".parse::<ExecutionInput>().unwrap();
assert_eq!(parsed.value, Value::String("hi".to_owned()));
}