1use std::ops::{Deref, DerefMut};
4
5use crate::error::Error;
6
7#[derive(Debug, Clone, PartialEq, serde::Serialize)]
8pub struct Params(pub serde_json::Value);
12
13impl Deref for Params {
14 type Target = serde_json::Value;
15
16 fn deref(&self) -> &Self::Target {
17 &self.0
18 }
19}
20
21impl DerefMut for Params {
22 fn deref_mut(&mut self) -> &mut Self::Target {
23 &mut self.0
24 }
25}
26
27impl<'de> serde::Deserialize<'de> for Params {
28 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
29 where
30 D: serde::Deserializer<'de>,
31 {
32 let value = serde_json::Value::deserialize(deserializer)?;
33 match value {
34 serde_json::Value::Object(_) | serde_json::Value::Array(_) => Ok(Params(value)),
35 _ => Err(serde::de::Error::custom(
36 r#""params" must be a JSON object or array"#,
37 )),
38 }
39 }
40}
41
42impl TryFrom<&str> for Params {
43 type Error = Error;
44
45 fn try_from(value: &str) -> Result<Self, Self::Error> {
46 serde_json::from_str(value).map_err(|e| e.into())
47 }
48}
49
50impl TryFrom<Params> for String {
51 type Error = Error;
52
53 fn try_from(value: Params) -> Result<Self, Self::Error> {
54 serde_json::to_string(&value).map_err(|e| e.into())
55 }
56}
57
58impl TryFrom<serde_json::Value> for Params {
59 type Error = Error;
60
61 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
62 match value {
63 serde_json::Value::Object(_) | serde_json::Value::Array(_) => Ok(Params(value)),
64 _ => Err(Error::Serde(serde::de::Error::custom(
65 r#""params" must be a JSON object or array"#,
66 ))),
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn params_object() {
77 let params = r#"{"val":123}"#;
78 let params_obj = TryInto::<Params>::try_into(params);
79 assert!(params_obj.is_ok());
80 }
81
82 #[test]
83 fn params_array() {
84 let params = r#"["hello","hi"]"#;
85 let params_obj = TryInto::<Params>::try_into(params);
86 assert!(params_obj.is_ok());
87 }
88
89 #[test]
90 fn params_negative_tests() {
91 let params = r#"12"#;
92 let params_obj = TryInto::<Params>::try_into(params);
93 assert!(params_obj.is_err());
94
95 let params = r#""hello""#;
96 let params_obj = TryInto::<Params>::try_into(params);
97 assert!(params_obj.is_err());
98
99 let params = r#""#;
100 let params_obj = TryInto::<Params>::try_into(params);
101 assert!(params_obj.is_err());
102
103 let params = r#"null"#;
104 let params_obj = TryInto::<Params>::try_into(params);
105 assert!(params_obj.is_err());
106 }
107}