jsonrpc_types/
id.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// Represents JSON-RPC request id.
7///
8/// An identifier established by the Client that MUST contain a String, Number,
9/// or NULL value if included, If it is not included it is assumed to be a notification.
10/// The value SHOULD normally not be Null and Numbers SHOULD NOT contain fractional parts.
11///
12/// The Server **MUST** reply with the same value in the Response object if included.
13/// This member is used to correlate the context between the two objects.
14#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
15#[serde(deny_unknown_fields)]
16#[serde(untagged)]
17pub enum Id {
18    /// Numeric id
19    Num(u64),
20    /// String id
21    Str(String),
22}
23
24impl Id {
25    /// If the `Id` is an Number, returns the associated number. Returns None
26    /// otherwise.
27    pub fn as_number(&self) -> Option<&u64> {
28        match self {
29            Self::Num(id) => Some(id),
30            _ => None,
31        }
32    }
33
34    /// If the `Id` is a String, returns the associated str. Returns None
35    /// otherwise.
36    pub fn as_str(&self) -> Option<&str> {
37        match self {
38            Self::Str(id) => Some(id),
39            _ => None,
40        }
41    }
42}
43
44impl fmt::Display for Id {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            Self::Num(id) => write!(f, "{}", id),
48            Self::Str(id) => f.write_str(id),
49        }
50    }
51}
52
53impl From<u64> for Id {
54    fn from(id: u64) -> Self {
55        Self::Num(id)
56    }
57}
58
59impl From<String> for Id {
60    fn from(id: String) -> Self {
61        Self::Str(id)
62    }
63}
64
65impl From<Id> for Value {
66    fn from(id: Id) -> Self {
67        match id {
68            Id::Num(id) => Self::Number(id.into()),
69            Id::Str(id) => Self::String(id),
70        }
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn id_serialization() {
80        let cases = vec![
81            (Id::Num(0), r#"0"#),
82            (Id::Str("1".into()), r#""1""#),
83            (Id::Str("test".into()), r#""test""#),
84        ];
85
86        for (id, expect) in cases {
87            assert_eq!(serde_json::to_string(&id).unwrap(), expect);
88            assert_eq!(id, serde_json::from_str(expect).unwrap());
89        }
90
91        assert_eq!(
92            serde_json::to_string(&vec![Id::Num(0), Id::Str("1".to_owned()), Id::Str("test".to_owned()),]).unwrap(),
93            r#"[0,"1","test"]"#
94        );
95    }
96}