jsonrpc_sys/
id.rs

1use std::borrow::Cow;
2
3use serde::de::{Deserialize, Deserializer, Visitor};
4use serde::ser::{Serialize, Serializer};
5
6/// A request identifier.
7///
8/// JSON-RPC 2.0 clients can use this to match responses sent back by a complying server
9/// with the request they sent. This is especially useful when sending multiple requests
10/// at the same time without waiting for a response in between.
11#[derive(Debug, Clone, PartialEq)]
12pub enum Id<'a> {
13    /// The ID was `null`.
14    Null,
15    /// The ID was a string.
16    Str(Cow<'a, str>),
17    /// The ID was a signed integer.
18    Int(i64),
19    /// The ID was an unsigned integer.
20    Uint(u64),
21    /// The ID was a floating point number.
22    ///
23    /// # Note
24    ///
25    /// THe JSON-RPC 2.0 specification specifies that a client *should not* use floating point
26    /// values as request IDs, but they technically are legal. For this reason, we have to
27    /// account for them.
28    Float(f64),
29}
30
31impl<'a> From<i64> for Id<'a> {
32    #[inline(always)]
33    fn from(id: i64) -> Self {
34        Self::Int(id)
35    }
36}
37
38impl<'a> From<u64> for Id<'a> {
39    #[inline(always)]
40    fn from(id: u64) -> Self {
41        Self::Uint(id)
42    }
43}
44
45impl<'a> From<f64> for Id<'a> {
46    #[inline(always)]
47    fn from(id: f64) -> Self {
48        Self::Float(id)
49    }
50}
51
52impl<'a> From<&'a str> for Id<'a> {
53    #[inline(always)]
54    fn from(id: &'a str) -> Self {
55        Self::Str(Cow::Borrowed(id))
56    }
57}
58
59impl<'a> From<String> for Id<'a> {
60    #[inline(always)]
61    fn from(id: String) -> Self {
62        Self::Str(Cow::Owned(id))
63    }
64}
65
66impl<'a> From<Cow<'a, str>> for Id<'a> {
67    #[inline(always)]
68    fn from(id: Cow<'a, str>) -> Self {
69        Self::Str(id)
70    }
71}
72
73impl<'a> Id<'a> {
74    /// Reborrows this [`Id`], creating a new instance without reallocating.
75    pub fn reborrow<'b>(&'b self) -> Id<'b>
76    where
77        'b: 'a,
78    {
79        match *self {
80            Self::Null => Self::Null,
81            Self::Str(ref s) => Self::Str(Cow::Borrowed(s)),
82            Self::Int(i) => Self::Int(i),
83            Self::Uint(u) => Self::Uint(u),
84            Self::Float(f) => Self::Float(f),
85        }
86    }
87}
88
89impl<'a> Serialize for Id<'a> {
90    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91    where
92        S: Serializer,
93    {
94        match *self {
95            Self::Null => serializer.serialize_none(),
96            Self::Float(f) => serializer.serialize_f64(f),
97            Self::Str(ref s) => serializer.serialize_str(s),
98            Self::Int(i) => serializer.serialize_i64(i),
99            Self::Uint(u) => serializer.serialize_u64(u),
100        }
101    }
102}
103
104impl<'de, 'a> Deserialize<'de> for Id<'a>
105where
106    'de: 'a,
107{
108    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109    where
110        D: Deserializer<'de>,
111    {
112        struct IdVisitor;
113
114        impl<'de> Visitor<'de> for IdVisitor {
115            type Value = crate::Id<'de>;
116
117            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
118                formatter.write_str("a JSON-RPC 2.0 ID")
119            }
120
121            fn visit_none<E>(self) -> Result<Self::Value, E>
122            where
123                E: serde::de::Error,
124            {
125                Ok(crate::Id::Null)
126            }
127
128            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
129            where
130                D: Deserializer<'de>,
131            {
132                deserializer.deserialize_any(self)
133            }
134
135            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
136            where
137                E: serde::de::Error,
138            {
139                Ok(crate::Id::Str(Cow::Borrowed(v)))
140            }
141
142            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
143            where
144                E: serde::de::Error,
145            {
146                Ok(crate::Id::Str(Cow::Owned(v.to_owned())))
147            }
148
149            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
150            where
151                E: serde::de::Error,
152            {
153                Ok(crate::Id::Str(Cow::Owned(v)))
154            }
155
156            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
157            where
158                E: serde::de::Error,
159            {
160                Ok(crate::Id::Int(v))
161            }
162
163            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
164            where
165                E: serde::de::Error,
166            {
167                Ok(crate::Id::Uint(v))
168            }
169
170            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
171            where
172                E: serde::de::Error,
173            {
174                Ok(crate::Id::Float(v))
175            }
176        }
177
178        deserializer.deserialize_option(IdVisitor)
179    }
180}