use std::collections::HashMap;
use tinyjson::JsonValue;
use super::error::StepFlowParseError;
pub fn jsonval_get_obj<'a>(val: &'a JsonValue, key: &str) -> Result<&'a HashMap<String, JsonValue>, StepFlowParseError> {
if let JsonValue::Object(o) = val {
Ok(o)
} else {
Err(StepFlowParseError::WrongType { key: key.to_owned(), expected: "Object".to_owned() })
}
}
pub fn jsonval_get_str<'a>(val: &'a JsonValue, key: &str) -> Result<&'a String, StepFlowParseError> {
if let JsonValue::String(s) = val {
Ok(s)
} else {
Err(StepFlowParseError::WrongType { key: key.to_owned(), expected: "String".to_owned() })
}
}
pub fn jsonval_get_u64(val: &JsonValue, key: &str) -> Result<u64, StepFlowParseError> {
if let JsonValue::Number(num) = val {
let uint = *num as u64;
if uint as f64 == *num {
Ok(uint)
} else {
Err(StepFlowParseError::WrongType { key: key.to_owned(), expected: "uint".to_owned() })
}
} else {
Err(StepFlowParseError::WrongType { key: key.to_owned(), expected: "Number".to_owned() })
}
}
pub fn jsonval_obj_get_u64(jsonobj: &HashMap<String, JsonValue>, key: &str) -> Result<u64, StepFlowParseError> {
if let Some(val) = jsonobj.get(key) {
jsonval_get_u64(val, key)
} else {
Err(StepFlowParseError::MissingValue(key.to_owned()))
}
}
pub fn jsonval_obj_get_obj<'a>(jsonobj: &'a HashMap<String, JsonValue>, key: &str) -> Result<&'a HashMap<String, JsonValue>, StepFlowParseError> {
if let Some(val) = jsonobj.get(key) {
jsonval_get_obj(val, key)
} else {
Err(StepFlowParseError::MissingValue(key.to_owned()))
}
}
pub fn jsonval_obj_get_str<'a>(jsonobj: &'a HashMap<String, JsonValue>, key: &str) -> Result<&'a String, StepFlowParseError> {
if let Some(val) = jsonobj.get(key) {
jsonval_get_str(val, key)
} else {
Err(StepFlowParseError::MissingValue(key.to_owned()))
}
}
pub fn jsonval_obj_get_vec<'a>(jsonobj: &'a HashMap<String, JsonValue>, key: &str) -> Result<&'a Vec<JsonValue>, StepFlowParseError> {
if let Some(val) = jsonobj.get(key) {
if let JsonValue::Array(arr) = val {
return Ok(arr);
} else {
return Err(StepFlowParseError::WrongType { key: key.to_owned(), expected: "Array".to_owned() });
}
} else {
return Err(StepFlowParseError::MissingValue(key.to_owned()));
}
}
pub fn jsonval_obj_get_vec_str<'a>(jsonobj: &'a HashMap<String, JsonValue>, key: &str)
-> Result<Vec<&'a String>, StepFlowParseError>
{
jsonval_obj_get_vec(jsonobj, key)
.and_then(|v| v.iter().map(|val| jsonval_get_str(val, key)).collect())
}
#[cfg(test)]
mod tests {
use tinyjson::JsonValue;
use super::jsonval_get_u64;
#[test]
fn u64_from_val() {
let tests = vec![
(JsonValue::Number(5.0), Some(5)),
(JsonValue::Number(5.5), None),
(JsonValue::Number(0.0), Some(0)),
(JsonValue::Number(-1.0), None),
(JsonValue::Number(u64::MAX as f64), Some(u64::MAX)),
(JsonValue::Number(f64::MAX), None),
(JsonValue::String("hi".to_owned()), None),
];
for test in tests {
let result = jsonval_get_u64(&test.0, "t");
if test.1 == None {
assert!(matches!(result, Err(_)));
} else {
assert_eq!(result.unwrap(), test.1.unwrap());
}
}
}
}