jrpc_types/
notification.rs

1//! This module implements the notification JSON-RPC object.
2
3use crate::{error::Error, params::Params};
4
5pub mod builder;
6
7#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
8/// The JSON-RPC Notification Object
9pub struct Notification {
10    #[serde(deserialize_with = "crate::version::version_deserialize")]
11    jsonrpc: String,
12    pub method: String,
13    pub params: Option<Params>,
14}
15
16impl Notification {
17    pub fn builder() -> builder::Builder<builder::MethodNone> {
18        builder::Builder::new()
19    }
20}
21
22impl TryFrom<&str> for Notification {
23    type Error = Error;
24
25    fn try_from(value: &str) -> Result<Self, Self::Error> {
26        serde_json::from_str(value).map_err(|e| e.into())
27    }
28}
29
30impl TryFrom<Notification> for String {
31    type Error = Error;
32
33    fn try_from(value: Notification) -> Result<Self, Self::Error> {
34        serde_json::to_string(&value).map_err(|e| e.into())
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn deserialize_spec_notifications() {
44        let req = r#"{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}"#;
45        let req_obj = TryInto::<Notification>::try_into(req);
46        assert!(req_obj.is_ok());
47        let req_obj = req_obj.unwrap();
48        assert_eq!(req_obj.jsonrpc, "2.0");
49        assert_eq!(req_obj.method, "update");
50
51        let req = r#"{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}"#;
52        let req_obj = TryInto::<Notification>::try_into(req);
53        assert!(req_obj.is_ok());
54        let req_obj = req_obj.unwrap();
55        assert_eq!(req_obj.jsonrpc, "2.0");
56        assert_eq!(req_obj.method, "notify_hello");
57
58        let req = r#"{"jsonrpc": "2.0", "method": "notify_hello", "params": {"hi":"hello"}}"#;
59        let req_obj = TryInto::<Notification>::try_into(req);
60        assert!(req_obj.is_ok());
61        let req_obj = req_obj.unwrap();
62        assert_eq!(req_obj.jsonrpc, "2.0");
63        assert_eq!(req_obj.method, "notify_hello");
64    }
65
66    #[test]
67    fn negative_serde_tests() {
68        let req = r#"{"jsonrpc": "2.0", "method": "subtract", "params": 1}"#; // params is number
69        let req_obj = TryInto::<Notification>::try_into(req);
70        assert!(req_obj.is_err());
71
72        let req = r#"{"jsonrpc": "2.0", "method": "subtract", "params": "hello"}"#; // params is string
73        let req_obj = TryInto::<Notification>::try_into(req);
74        assert!(req_obj.is_err());
75
76        let req = r#"{"jsonrpc": "2.1", "method": "subtract"}"#; // jsonrpc version wrong
77        let req_obj = TryInto::<Notification>::try_into(req);
78        assert!(req_obj.is_err());
79
80        let req = r#"{"jsonrpc": 2.0, "method": "subtract"}"#; // jsonrpc version string
81        let req_obj = TryInto::<Notification>::try_into(req);
82        assert!(req_obj.is_err());
83
84        let req = r#"{"jsonrpc": 2.0, "method": "subtract", id: 2}"#; // id exists (i.e. a request)
85        let req_obj = TryInto::<Notification>::try_into(req);
86        assert!(req_obj.is_err());
87    }
88
89    #[test]
90    fn builder() {
91        let params = vec![10, 0];
92        let req = Notification::builder()
93            .method("test-notification")
94            .params(params)
95            .unwrap()
96            .build();
97        let req_str = TryInto::<String>::try_into(req).unwrap();
98        let new_req = TryInto::<Notification>::try_into(req_str.as_str());
99        assert!(new_req.is_ok());
100    }
101}