ez_jsonrpc_types/
_template.rs

1use core::{fmt, hash::Hash, marker::PhantomData, ops::RangeInclusive, str::FromStr};
2use serde::{
3    de::{
4        self,
5        value::{
6            EnumAccessDeserializer, MapAccessDeserializer, SeqAccessDeserializer, UnitDeserializer,
7        },
8        Error as _,
9    },
10    Deserialize, Deserializer, Serialize, Serializer,
11};
12use serde_json::{Number, Value};
13use std::collections::BTreeMap;
14
15/// A `JSON-RPC 2.0` request object.
16///
17/// Note that the `"jsonrpc": "2.0"` member is transparently checked during
18/// deserialization, and added during serialization.
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct Request<MethodT = String, IdT = Id, RequestParametersT = RequestParameters<Value>> {
21    /// > A String containing the name of the method to be invoked.
22    /// > Method names that begin with the word rpc followed by a period character
23    /// > (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions
24    /// > and MUST NOT be used for anything else.
25    pub method: MethodT,
26    /// > A Structured value that holds the parameter values to be used during the
27    /// > invocation of the method.
28    /// > This member MAY be omitted.
29    pub params: Option<RequestParametersT>,
30    /// > An identifier established by the Client that MUST contain a String,
31    /// > Number, or NULL value if included.
32    /// > If it is not included it is assumed to be a notification.
33    /// > The value SHOULD normally not be Null and Numbers SHOULD NOT contain fractional parts
34    pub id: Option<IdT>,
35}
36
37impl<MethodT: Default, IdT, RequestParametersT> Default
38    for Request<MethodT, IdT, RequestParametersT>
39{
40    fn default() -> Self {
41        Self {
42            method: Default::default(),
43            params: Default::default(),
44            id: Default::default(),
45        }
46    }
47}
48
49impl<MEthodT, ParametersT, IdT> Serialize for Request<MEthodT, ParametersT, IdT>
50where
51    MEthodT: Serialize,
52    ParametersT: Serialize,
53    IdT: Serialize,
54{
55    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
56    where
57        S: serde::Serializer,
58    {
59        #[derive(Serialize)]
60        struct _Request<MethodT, IdT, RequestParametersT> {
61            jsonrpc: V2,
62            method: MethodT,
63            #[serde(skip_serializing_if = "Option::is_none")]
64            params: Option<RequestParametersT>,
65            #[serde(skip_serializing_if = "Option::is_none")]
66            id: Option<IdT>,
67        }
68        let Self { method, params, id } = self;
69        _Request {
70            jsonrpc: V2,
71            method,
72            params: params.as_ref(),
73            id: id.as_ref(),
74        }
75        .serialize(serializer)
76    }
77}
78
79impl<'de, MethodT, IdT, RequestParametersT> Deserialize<'de>
80    for Request<MethodT, IdT, RequestParametersT>
81where
82    MethodT: Deserialize<'de>,
83    IdT: Deserialize<'de>,
84    RequestParametersT: Deserialize<'de>,
85{
86    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87    where
88        D: serde::Deserializer<'de>,
89    {
90        #[derive(Deserialize)]
91        #[serde(bound(deserialize = "
92            IdT: Deserialize<'de>,
93            MethodT: Deserialize<'de>,
94            RequestParametersT: Deserialize<'de>
95        "))]
96        struct _Request<MethodT, IdT, RequestParametersT> {
97            jsonrpc: V2,
98            method: MethodT,
99            params: Option<RequestParametersT>,
100            #[serde(deserialize_with = "deserialize_some", default)]
101            id: Option<IdT>,
102        }
103        let _Request {
104            method,
105            params,
106            id,
107            jsonrpc: V2,
108        } = _Request::deserialize(deserializer)?;
109        Ok(Self { method, params, id })
110    }
111}
112
113impl<T> Request<T> {
114    pub const fn is_notification(&self) -> bool {
115        self.id.is_none()
116    }
117}
118
119/// > A String specifying the version of the JSON-RPC protocol.
120/// > MUST be exactly "2.0".
121#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
122struct V2;
123
124impl<'de> Deserialize<'de> for V2 {
125    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
126        struct Visitor;
127        impl de::Visitor<'_> for Visitor {
128            type Value = V2;
129            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
130                f.write_str("the string `2.0`")
131            }
132            fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
133                (v == "2.0")
134                    .then_some(V2)
135                    .ok_or_else(|| E::invalid_value(de::Unexpected::Str(v), &"2.0"))
136            }
137        }
138        deserializer.deserialize_str(Visitor)
139    }
140}
141
142impl Serialize for V2 {
143    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
144        serializer.serialize_str("2.0")
145    }
146}
147
148/// > If present, parameters for the rpc call MUST be provided as a Structured value.
149/// > Either by-position through an Array or by-name through an Object.
150#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
151#[serde(untagged)]
152pub enum RequestParameters<ValueT = Value> {
153    /// > params MUST be an Array, containing the values in the Server expected order.
154    ByPosition(Vec<ValueT>),
155    /// > params MUST be an Object, with member names that match the Server
156    /// > expected parameter names.
157    /// > The absence of expected names MAY result in an error being generated.
158    /// > The names MUST match exactly, including case, to the method's expected parameters.
159    ByName(BTreeMap<String, ValueT>),
160}
161
162impl<'de, ValueT: Deserialize<'de>> Deserialize<'de> for RequestParameters<ValueT> {
163    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
164        struct Visitor<ValueT>(PhantomData<fn() -> ValueT>);
165        impl<'de, ValueT: Deserialize<'de>> serde::de::Visitor<'de> for Visitor<ValueT> {
166            type Value = RequestParameters<ValueT>;
167            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
168                f.write_str(
169                    "An Array of by-position parameters, or an Object of by-name parameters",
170                )
171            }
172            fn visit_map<A: de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
173                let mut by_name = BTreeMap::new();
174                while let Some((k, v)) = map.next_entry()? {
175                    by_name.insert(k, v);
176                }
177                Ok(RequestParameters::ByName(by_name))
178            }
179            fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
180                let mut by_pos = Vec::new();
181                while let Some(it) = seq.next_element()? {
182                    by_pos.push(it)
183                }
184                Ok(RequestParameters::ByPosition(by_pos))
185            }
186        }
187        d.deserialize_any(Visitor(PhantomData))
188    }
189}
190
191impl<T> RequestParameters<T> {
192    pub fn len(&self) -> usize {
193        match self {
194            RequestParameters::ByPosition(it) => it.len(),
195            RequestParameters::ByName(it) => it.len(),
196        }
197    }
198    pub fn is_empty(&self) -> bool {
199        match self {
200            RequestParameters::ByPosition(it) => it.is_empty(),
201            RequestParameters::ByName(it) => it.is_empty(),
202        }
203    }
204}
205
206#[doc(inline)]
207pub use crate::params::IntoDeserializer;
208
209/// See [`Request::id`].
210#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
211#[serde(untagged)]
212pub enum Id<StringT = String, NumberT = Number> {
213    String(StringT),
214    Number(NumberT),
215    Null,
216}
217
218impl<'de, StringT: Deserialize<'de>, NumberT: Deserialize<'de>> Deserialize<'de>
219    for Id<StringT, NumberT>
220{
221    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
222        use serde::de::value::*;
223        struct Visitor<StringT, NumberT>(PhantomData<fn() -> (StringT, NumberT)>);
224        macro_rules! fwd_number {
225            ($($method:ident($input:ty) via $deserializer:ident);*$(;)?) => {$(
226                fn $method<E: de::Error>(self, v: $input) -> Result<Self::Value, E> {
227                    Ok(Id::Number(NumberT::deserialize($deserializer::new(v))?))
228                }
229            )*};
230        }
231        impl<'de, StringT: Deserialize<'de>, NumberT: Deserialize<'de>> de::Visitor<'de>
232            for Visitor<StringT, NumberT>
233        {
234            type Value = Id<StringT, NumberT>;
235            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
236                f.write_str("a string, a number, or null")
237            }
238            fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
239                Ok(Id::Null)
240            }
241            fwd_number! {
242                visit_i8(i8) via I8Deserializer;
243                visit_i16(i16) via I16Deserializer;
244                visit_i32(i32) via I32Deserializer;
245                visit_i64(i64) via I64Deserializer;
246                visit_i128(i128) via I128Deserializer;
247
248                visit_u8(u8) via U8Deserializer;
249                visit_u16(u16) via U16Deserializer;
250                visit_u32(u32) via U32Deserializer;
251                visit_u64(u64) via U64Deserializer;
252                visit_u128(u128) via U128Deserializer;
253
254                visit_f32(f32) via F32Deserializer;
255                visit_f64(f64) via F64Deserializer;
256            }
257            fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
258                Ok(Id::String(StringT::deserialize(StrDeserializer::new(v))?))
259            }
260            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
261                Ok(Id::String(StringT::deserialize(StrDeserializer::new(v))?))
262            }
263            fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
264                Ok(Id::String(StringT::deserialize(StringDeserializer::new(
265                    v,
266                ))?))
267            }
268            fn visit_some<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
269                d.deserialize_any(self)
270            }
271            fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
272                Ok(Id::Null)
273            }
274        }
275        d.deserialize_any(Visitor(PhantomData))
276    }
277}
278
279impl<StringT, NumberT> Default for Id<StringT, NumberT> {
280    fn default() -> Self {
281        Self::Null
282    }
283}
284
285impl FromStr for Id {
286    type Err = serde_json::Error;
287
288    fn from_str(s: &str) -> Result<Self, Self::Err> {
289        serde_json::from_str(s)
290    }
291}
292
293/// A `JSON-RPC 2.0` response object.
294///
295/// Note that the `"jsonrpc": "2.0"` member is transparently checked during
296/// deserialization, and added during serialization.
297#[derive(Debug, Clone, PartialEq, Eq)]
298pub struct Response<ValueT = Value, ValueE = Value, StringE = String, IdT = Id> {
299    /// > "result":
300    /// >
301    /// > This member is REQUIRED on success.
302    /// > This member MUST NOT exist if there was an error invoking the method.
303    /// > The value of this member is determined by the method invoked on the Server.
304    /// >
305    /// > "error":
306    /// >
307    /// > This member is REQUIRED on error.
308    /// > This member MUST NOT exist if there was no error triggered during invocation.
309    pub result: Result<ValueT, Error<ValueE, StringE>>,
310    /// > This member is REQUIRED.
311    /// > It MUST be the same as the value of the id member in the Request Object.
312    /// > If there was an error in detecting the id in the Request object
313    /// > (e.g. Parse error/Invalid Request), it MUST be Null.
314    pub id: IdT,
315}
316
317impl<'de, ValueT, ValueE, StringE, IdT> Deserialize<'de> for Response<ValueT, ValueE, StringE, IdT>
318where
319    ValueT: Deserialize<'de>,
320    ValueE: Deserialize<'de>,
321    StringE: Deserialize<'de>,
322    IdT: Deserialize<'de>,
323{
324    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
325    where
326        D: de::Deserializer<'de>,
327    {
328        #[derive(Deserialize)]
329        #[serde(bound(deserialize = "
330            ValueT: Deserialize<'de>,
331            ValueE: Deserialize<'de>,
332            StringT: Deserialize<'de>,
333            IdT: Deserialize<'de>,
334        "))]
335        struct _Response<ValueT, ValueE, StringT, IdT> {
336            jsonrpc: V2,
337            #[serde(default, deserialize_with = "deserialize_some")]
338            result: Option<Option<ValueT>>,
339            #[serde(default, deserialize_with = "deserialize_some")]
340            error: Option<Error<ValueE, StringT>>,
341            id: IdT,
342        }
343        let _Response {
344            jsonrpc: V2,
345            result,
346            error,
347            id,
348        } = _Response::deserialize(deserializer)?;
349
350        match (result, error) {
351            (Some(Some(ok)), None) => Ok(Response { result: Ok(ok), id }),
352            (None, Some(err)) => Ok(Response {
353                result: Err(err),
354                id,
355            }),
356
357            (Some(_), Some(_)) => Err(D::Error::custom(
358                "only ONE of `error` and `result` may be present",
359            )),
360            (None, None) => Err(D::Error::custom("must have an `error` or `result` member")),
361
362            (Some(None), None) => Ok(Response {
363                result: Ok(ValueT::deserialize(
364                    serde::de::value::UnitDeserializer::new(),
365                )?),
366                id,
367            }),
368        }
369    }
370}
371
372impl<ValueT, ValueE, StringE, IdT> Serialize for Response<ValueT, ValueE, StringE, IdT>
373where
374    ValueT: Serialize,
375    ValueE: Serialize,
376    StringE: Serialize,
377    IdT: Serialize,
378{
379    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
380    where
381        S: serde::Serializer,
382    {
383        #[derive(Serialize)]
384        struct _Response<ValueT, ValueE, StringE, IdT> {
385            jsonrpc: V2,
386            #[serde(skip_serializing_if = "Option::is_none")]
387            result: Option<Option<ValueT>>,
388            #[serde(skip_serializing_if = "Option::is_none")]
389            error: Option<Error<ValueE, StringE>>,
390            id: IdT,
391        }
392        let Self { result, id } = self;
393        match result {
394            Ok(it) => _Response {
395                jsonrpc: V2,
396                result: Some(Some(it)),
397                error: None,
398                id,
399            },
400            Err(Error {
401                code,
402                message,
403                data,
404            }) => _Response {
405                jsonrpc: V2,
406                result: None,
407                error: Some(Error {
408                    code: *code,
409                    message,
410                    data: data.as_ref(),
411                }),
412                id,
413            },
414        }
415        .serialize(serializer)
416    }
417}
418
419/// Distinguish between absent and present but null.
420///
421/// See <https://github.com/serde-rs/serde/issues/984#issuecomment-314143738>
422fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
423where
424    T: Deserialize<'de>,
425    D: serde::de::Deserializer<'de>,
426{
427    Deserialize::deserialize(deserializer).map(Some)
428}
429
430/// A `JSON-RPC 2.0` error object.
431#[derive(Serialize, Debug, Clone, PartialEq, Eq, Deserialize)]
432pub struct Error<ValueT = Value, StringT = String> {
433    /// > A Number that indicates the error type that occurred.
434    /// > This MUST be an integer.
435    ///
436    /// See the associated constants for error types defined by the specification.
437    pub code: i64,
438    /// > A String providing a short description of the error.
439    /// > The message SHOULD be limited to a concise single sentence.
440    pub message: StringT,
441    /// > A Primitive or Structured value that contains additional information about the error.
442    /// > This may be omitted.
443    /// > The value of this member is defined by the Server
444    /// > (e.g. detailed error information, nested errors etc.).
445    #[serde(skip_serializing_if = "Option::is_none")]
446    pub data: Option<ValueT>,
447}
448
449impl<ValueT, StringT: Default> Default for Error<ValueT, StringT> {
450    fn default() -> Self {
451        Self {
452            code: Default::default(),
453            message: Default::default(),
454            data: Default::default(),
455        }
456    }
457}
458
459macro_rules! error_code_and_ctor {
460    (
461        $(
462            $(#[doc = $doc:literal])*
463            $const_name:ident / $ctor_name:ident = $number:literal;
464        )*
465    ) => {
466
467        impl Error {
468            $(
469                $(#[doc = $doc])*
470                pub const $const_name: i64 = $number;
471            )*
472
473        }
474
475        impl Error {
476
477            $(
478                #[doc = concat!("Convenience method for creating a new error with code [`Self::", stringify!($const_name), "`]")]
479                pub fn $ctor_name(message: impl fmt::Display, data: impl Into<Option<Value>>) -> Self {
480                    Self::new(Error::$const_name, message, data)
481                }
482            )*
483        }
484
485        impl<ValueT, StringT> Error<ValueT, StringT> {
486            /// If [`Self::code`] is one of the predefined errors in the spec,
487            /// get its associated error message.
488            pub const fn spec_message(&self) -> Option<&'static str> {
489                match self.code {
490                    $(
491                        Error::$const_name => {
492                            const LIMBS: &[&'static str] = &[
493                                $($doc),*
494                            ];
495                            const LIMB: &str = LIMBS[0];
496                            const MESSAGE: &str = {
497                                let (_quot, rest) = LIMB.as_bytes().split_at(2);
498                                match std::str::from_utf8(rest) {
499                                    Ok(it) => it,
500                                    Err(_) => panic!()
501                                }
502                            };
503                            Some(MESSAGE)
504                        },
505                    )*
506                    _ => None
507                    }
508                }
509            }
510        }
511    }
512
513error_code_and_ctor! {
514    /// > Invalid JSON was received by the server.
515    /// > An error occurred on the server while parsing the JSON text.
516    PARSE_ERROR / parse_error = -32700;
517    /// > The JSON sent is not a valid Request object.
518    INVALID_REQUEST / invalid_request = -32600;
519    /// > The method does not exist / is not available.
520    METHOD_NOT_FOUND / method_not_found = -32601;
521    /// > Invalid method parameter(s).
522    INVALID_PARAMS / invalid_params = -32602;
523    /// > Internal JSON-RPC error.
524    INTERNAL_ERROR / internal_error = -32603;
525}
526
527impl Error {
528    /// > Reserved for implementation-defined server-errors.
529    pub const SERVER_ERROR_RANGE: RangeInclusive<i64> = -32099..=-32000;
530}
531
532impl Error {
533    /// Convenience method for creating a new error.
534    pub fn new(code: i64, message: impl fmt::Display, data: impl Into<Option<Value>>) -> Self {
535        Self {
536            code,
537            message: message.to_string(),
538            data: data.into(),
539        }
540    }
541}
542
543impl<ValueT, StringT> fmt::Display for Error<ValueT, StringT>
544where
545    StringT: fmt::Display,
546{
547    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
548        f.write_fmt(format_args!("code {}", self.code))?;
549        if let Some(e) = self.spec_message() {
550            f.write_fmt(format_args!(" ({})", e))?
551        };
552        f.write_fmt(format_args!(": `{}`", self.message))
553    }
554}
555
556impl<ValueT, StringT> std::error::Error for Error<ValueT, StringT>
557where
558    StringT: fmt::Display + fmt::Debug,
559    ValueT: fmt::Debug,
560{
561}
562
563/// A response to a [`MaybeBatchedRequest`].
564#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
565#[serde(untagged)]
566pub enum MaybeBatchedResponse<ValueT = Value, ValueE = Value, StringE = String, IdT = Id> {
567    Single(Response<ValueT, ValueE, StringE, IdT>),
568    Batch(Vec<Response<ValueT, ValueE, StringE, IdT>>),
569}
570
571impl<
572        'de,
573        ValueT: Deserialize<'de>,
574        ValueE: Deserialize<'de>,
575        StringE: Deserialize<'de>,
576        IdT: Deserialize<'de>,
577    > Deserialize<'de> for MaybeBatchedResponse<ValueT, ValueE, StringE, IdT>
578{
579    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
580        struct Visitor<'de, ValueT, ValueE, StringE, IdT>(
581            #[expect(clippy::type_complexity)]
582            PhantomData<fn() -> (&'de (), ValueT, ValueE, StringE, IdT)>,
583        );
584        impl<
585                'de,
586                ValueT: Deserialize<'de>,
587                ValueE: Deserialize<'de>,
588                StringE: Deserialize<'de>,
589                IdT: Deserialize<'de>,
590            > de::Visitor<'de> for Visitor<'de, ValueT, ValueE, StringE, IdT>
591        {
592            type Value = MaybeBatchedResponse<ValueT, ValueE, StringE, IdT>;
593            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
594                f.write_str("a single response object, or an Array of batched response objects")
595            }
596            fn visit_newtype_struct<D: Deserializer<'de>>(
597                self,
598                d: D,
599            ) -> Result<Self::Value, D::Error> {
600                d.deserialize_any(self)
601            }
602            fn visit_seq<A: de::SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
603                Ok(MaybeBatchedResponse::Batch(Deserialize::deserialize(
604                    SeqAccessDeserializer::new(seq),
605                )?))
606            }
607            fn visit_map<A: de::MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
608                Ok(MaybeBatchedResponse::Single(Deserialize::deserialize(
609                    MapAccessDeserializer::new(map),
610                )?))
611            }
612
613            fn visit_enum<A: de::EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
614                Ok(MaybeBatchedResponse::Single(Deserialize::deserialize(
615                    EnumAccessDeserializer::new(data),
616                )?))
617            }
618        }
619        d.deserialize_map(Visitor(PhantomData))
620    }
621}
622
623/// > To send several Request objects at the same time, the Client MAY send an Array filled with Request objects.
624#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
625#[serde(untagged)]
626pub enum MaybeBatchedRequest<MethodT = String, IdT = Id, RequestParametersT = RequestParameters> {
627    Single(Request<MethodT, IdT, RequestParametersT>),
628    Batch(Vec<Request<MethodT, IdT, RequestParametersT>>),
629}
630
631impl<
632        'de,
633        MethodT: Deserialize<'de>,
634        IdT: Deserialize<'de>,
635        RequestParametersT: Deserialize<'de>,
636    > Deserialize<'de> for MaybeBatchedRequest<MethodT, IdT, RequestParametersT>
637{
638    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
639        #[expect(clippy::type_complexity)]
640        struct Visitor<MethodT, IdT, RequestParametersT>(
641            PhantomData<fn() -> (MethodT, IdT, RequestParametersT)>,
642        );
643
644        impl<
645                'de,
646                MethodT: Deserialize<'de>,
647                IdT: Deserialize<'de>,
648                RequestParametersT: Deserialize<'de>,
649            > de::Visitor<'de> for Visitor<MethodT, IdT, RequestParametersT>
650        {
651            type Value = MaybeBatchedRequest<MethodT, IdT, RequestParametersT>;
652            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
653                f.write_str("a single request object, or an array or request objects")
654            }
655            fn visit_newtype_struct<D: Deserializer<'de>>(
656                self,
657                d: D,
658            ) -> Result<Self::Value, D::Error> {
659                d.deserialize_any(self)
660            }
661            fn visit_seq<A: de::SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
662                Ok(MaybeBatchedRequest::Batch(Deserialize::deserialize(
663                    SeqAccessDeserializer::new(seq),
664                )?))
665            }
666            fn visit_map<A: de::MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
667                Ok(MaybeBatchedRequest::Single(Deserialize::deserialize(
668                    MapAccessDeserializer::new(map),
669                )?))
670            }
671
672            fn visit_enum<A: de::EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
673                Ok(MaybeBatchedRequest::Single(Deserialize::deserialize(
674                    EnumAccessDeserializer::new(data),
675                )?))
676            }
677        }
678        d.deserialize_map(Visitor(PhantomData))
679    }
680}
681
682#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
683#[serde(untagged)]
684pub enum Message<
685    MethodT = String,
686    IdT = Id,
687    RequestParametersT = RequestParameters,
688    ValueT = Value,
689    ValueE = ValueT,
690    StringE = String,
691> {
692    Request(Request<MethodT, IdT, RequestParametersT>),
693    Response(Response<ValueT, ValueE, StringE, IdT>),
694}
695
696impl<
697        'de,
698        MethodT: Deserialize<'de>,
699        IdT: Deserialize<'de>,
700        RequestParametersT: Deserialize<'de>,
701        ValueT: Deserialize<'de>,
702        ValueE: Deserialize<'de>,
703        StringE: Deserialize<'de>,
704    > Deserialize<'de> for Message<MethodT, IdT, RequestParametersT, ValueT, ValueE, StringE>
705{
706    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
707        #[derive(Deserialize)]
708        #[serde(bound(deserialize = "
709            IdT: Deserialize<'de>,
710            MethodT: Deserialize<'de>,
711            RequestParametersT: Deserialize<'de>,
712            ValueT: Deserialize<'de>,
713            ValueE: Deserialize<'de>,
714            StringE: Deserialize<'de>,
715        "))]
716        struct _Message<MethodT, IdT, RequestParametersT, ValueT, ValueE, StringE> {
717            jsonrpc: V2,
718            method: Option<MethodT>,
719            params: Option<RequestParametersT>,
720            #[serde(deserialize_with = "deserialize_some", default)]
721            id: Option<IdT>,
722            #[serde(default, deserialize_with = "deserialize_some")]
723            result: Option<Option<ValueT>>,
724            #[serde(default, deserialize_with = "deserialize_some")]
725            error: Option<Error<ValueE, StringE>>,
726        }
727        let _Message {
728            jsonrpc: V2,
729            method,
730            params,
731            id,
732            result,
733            error,
734        } = _Message::deserialize(d)?;
735
736        match (method, params, id, result, error) {
737            (Some(method), params, id, None, None) => {
738                Ok(Self::Request(Request { method, params, id }))
739            }
740            (None, None, Some(id), Some(Some(res)), None) => Ok(Self::Response(Response {
741                result: Ok(res),
742                id,
743            })),
744            (None, None, Some(id), Some(None), None) => Ok(Self::Response(Response {
745                result: Ok(Deserialize::deserialize(UnitDeserializer::new())?),
746                id,
747            })),
748            (None, None, Some(id), None, Some(err)) => Ok(Self::Response(Response {
749                result: Err(err),
750                id,
751            })),
752            _ => Err(serde::de::Error::custom(
753                "bad field set: `method` (possibly with `params`), `result` and `error` are mutually exclusive",
754            )),
755        }
756    }
757}