jrpc_types/
params.rs

1//! This module implements the structure for the "params" field in JSON-RPC objects.
2
3use std::ops::{Deref, DerefMut};
4
5use crate::error::Error;
6
7#[derive(Debug, Clone, PartialEq, serde::Serialize)]
8/// This object implements the "params" field in JSON-RPC objects.
9///
10/// "params" can only be a Structured Value (by-name, by-position)
11pub 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}