jsonrpc_core/types/
params.rs

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