diff options
Diffstat (limited to 'src/parameter.rs')
| -rw-r--r-- | src/parameter.rs | 114 |
1 files changed, 19 insertions, 95 deletions
diff --git a/src/parameter.rs b/src/parameter.rs index 29d1990..be846a1 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -1,35 +1,22 @@ -use serde_json::{Value, json}; -use serde::{de, Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Serialize, Deserialize}; use strum_macros::{EnumString, Display}; use crate::{ Template, - Pos, - PResult, - perr }; macro_rules! parameters { - ($($name: ident ($typ: ty) $stringname: ident, $v: ident ($fromjson: expr) ($tojson: expr));*;) => { - #[derive(Debug, PartialEq, Clone)] + {$($name: ident $typ: ty);*;} => { + #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] + #[serde(untagged)] pub enum Parameter { $( $name($typ), )* } impl Parameter { - pub fn from_typed_json(typ: ParameterType, val: &Value) -> PResult<Parameter>{ - match typ { - $( - ParameterType::$name => Ok(Self::$name({ - let $v = val; - $fromjson - })), - )* - } - } pub fn paramtype(&self) -> ParameterType { match self { $( @@ -37,13 +24,6 @@ macro_rules! parameters { )* } } - pub fn to_json(&self) -> Value { - match self { - $( - Self::$name($v) => $tojson, - )* - } - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, EnumString, Display)] @@ -54,36 +34,17 @@ macro_rules! parameters { $name, )* } - impl ParameterType { - pub fn from_str(typename: &str) -> Option<Self>{ - match typename { - $( - stringify!($stringname) => Some(Self::$name), - )* - _ => None - } - } - } } } -parameters!( - String (String) string, v (v.as_str().ok_or(perr!("{:?} not a string", v))?.to_string()) (json!(v)); - Int (i64) int, v (v.as_i64().ok_or(perr!("{:?} not an int", v))?) (json!(v)); - Pos (Pos) pos, v (Pos::deserialize(v).map_err(|e| perr!("{:?} not a pos {}", v, e))?) (json!(v)); - Float (f64) float, v (v.as_f64().ok_or(perr!("{:?} not an float", v))?) (json!(v)); - Template (Template) template, v (Template::deserialize(v).map_err(|e| perr!("template json error {:?}", e))?) (json!(["template", v])); - Bool (bool) bool, v (v.as_bool().ok_or(perr!("{:?} not a bool", v))?) (json!(v)); - List (Vec<Parameter>) list, v - ({ - v - .as_array().ok_or(perr!("{:?} not an array", v))? - .iter() - .map(|item| Parameter::guess_from_json(item)) - .collect::<PResult<Vec<Parameter>>>()? - }) - (json!(["list", v.iter().map(Parameter::to_json).collect::<Vec<Value>>()])); -); +parameters!{ + String String; + Int i64; + Float f64; + Template Template; + Bool bool; + List Vec<Parameter>; +} impl Parameter { @@ -92,58 +53,21 @@ impl Parameter { Self::String(string.to_string()) } - pub fn guess_from_json(val: &Value) -> PResult<Parameter> { - if let Some(arr) = val.as_array() { - if arr.len() == 2 && arr[0].is_string() { - let typestr = arr[0].as_str().unwrap(); - let typ = ParameterType::from_str(typestr).ok_or(perr!("invalid parameter type {}", typestr))?; - return Self::from_typed_json(typ, &arr[1]); - } - } - let typ = - if val.is_string() { - ParameterType::String - } else if val.is_u64() || val.is_i64() { - ParameterType::Int - } else if val.is_f64() { - ParameterType::Float - } else if val.is_boolean(){ - ParameterType::Bool - } else if val.is_object(){ - ParameterType::Template - } else { - return Err(perr!("can't guess the type of parameter {:?}", val)); - }; - Self::from_typed_json(typ, val) - } } -impl Serialize for Parameter { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where S: Serializer { - self.to_json().serialize(serializer) - } -} -impl<'de> Deserialize<'de> for Parameter { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where D: Deserializer<'de> { - Self::guess_from_json(&Value::deserialize(deserializer)?).map_err(|e| de::Error::custom(e.text)) - } -} - #[cfg(test)] mod tests { use super::*; use serde_json::json; macro_rules! gfj { // guess from json - ($($j:tt)*) => {Parameter::guess_from_json(&json!($($j)*)).unwrap()} + ($($j:tt)*) => {Parameter::deserialize(&json!($($j)*)).unwrap()} } #[test] fn can_guess_json() { - Parameter::guess_from_json(&json!(3)).unwrap(); + Parameter::deserialize(&json!(3)).unwrap(); } #[test] @@ -162,19 +86,19 @@ mod tests { assert_eq!(gfj!(-0.0), Parameter::Float(0.0)); assert_eq!(gfj!(true), Parameter::Bool(true)); - assert_eq!(gfj!(["int", 3]), Parameter::Int(3)); + assert_eq!(gfj!(["int", 3]), Parameter::List(vec![Parameter::string("int"), Parameter::Int(3)])); + assert_eq!(gfj!([2, 5]), Parameter::List(vec![Parameter::Int(2), Parameter::Int(5)])); } #[test] fn guess_json_none() { - assert!(Parameter::guess_from_json(&json!([2, 5])).is_err()); - assert!(Parameter::guess_from_json(&json!({"hello": "world"})).is_err()); + assert!(Parameter::deserialize(&json!({"hello": "world"})).is_err()); } #[test] fn parse_list() { assert_eq!( - gfj!(["list", [5, 3, 1, 2]]), + gfj!([5, 3, 1, 2]), Parameter::List(vec![ Parameter::Int(5), Parameter::Int(3), @@ -183,7 +107,7 @@ mod tests { ]) ); assert_eq!( - gfj!(["list", [5, 3.0, "Hello", true]]), + gfj!([5, 3.0, "Hello", true]), Parameter::List(vec