1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::error::ParamsError as Error;
use crate::JsonValue;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::{from_value, Value};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(untagged)]
pub enum Params {
None,
Array(Vec<JsonValue>),
Map(serde_json::Map<String, JsonValue>),
}
impl Params {
pub fn parse<D>(self) -> Result<D, Error>
where
D: DeserializeOwned,
{
let value: JsonValue = self.into();
from_value(value).map_err(|e| Error::InvalidParams(format!("Invalid params: {}.", e)))
}
pub fn to_value(&self) -> Value {
match self {
Params::None => JsonValue::Null,
Params::Array(a) => Value::Array(a.clone()),
Params::Map(a) => Value::Object(a.clone()),
}
}
pub fn expect_no_params(self) -> Result<(), Error> {
match self {
Params::None => Ok(()),
Params::Array(ref v) if v.is_empty() => Ok(()),
_ => Err(Error::InvalidParams(
"No parameters were expected".to_string(),
)),
}
}
}
impl From<Params> for JsonValue {
fn from(params: Params) -> JsonValue {
match params {
Params::Array(vec) => JsonValue::Array(vec),
Params::Map(map) => JsonValue::Object(map),
Params::None => JsonValue::Null,
}
}
}
#[cfg(test)]
mod tests {
use super::Params;
use crate::common::{Error, ErrorCode, JsonValue};
use serde_json;
#[test]
fn params_deserialization() {
let s = r#"[null, true, -1, 4, 2.3, "hello", [0], {"key": "value"}, []]"#;
let deserialized: Params = serde_json::from_str(s).unwrap();
let mut map = serde_json::Map::new();
map.insert("key".to_string(), JsonValue::String("value".to_string()));
assert_eq!(
Params::Array(vec![
JsonValue::Null,
JsonValue::Bool(true),
JsonValue::from(-1),
JsonValue::from(4),
JsonValue::from(2.3),
JsonValue::String("hello".to_string()),
JsonValue::Array(vec![JsonValue::from(0)]),
JsonValue::Object(map),
JsonValue::Array(vec![]),
]),
deserialized
);
}
#[test]
fn should_return_meaningful_error_when_deserialization_fails() {
let s = r#"[1, true]"#;
let params = || serde_json::from_str::<Params>(s).unwrap();
let v1: Result<(Option<u8>, String), Error> = params().parse();
let v2: Result<(u8, bool, String), Error> = params().parse();
let err1 = v1.unwrap_err();
let err2 = v2.unwrap_err();
assert_eq!(err1.code, ErrorCode::InvalidParams);
assert_eq!(
err1.message,
"Invalid params: invalid type: boolean `true`, expected a string."
);
assert_eq!(err1.data, None);
assert_eq!(err2.code, ErrorCode::InvalidParams);
assert_eq!(
err2.message,
"Invalid params: invalid length 2, expected a tuple of size 3."
);
assert_eq!(err2.data, None);
}
#[test]
fn single_param_parsed_as_tuple() {
let params: (u64,) = Params::Array(vec![JsonValue::from(1)]).parse().unwrap();
assert_eq!(params, (1,));
}
}