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#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct Request<MethodT = String, IdT = Id, RequestParametersT = RequestParameters<Value>> {
21 pub method: MethodT,
26 pub params: Option<RequestParametersT>,
30 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#[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#[derive(Serialize, Debug, Clone, PartialEq, Eq)]
151#[serde(untagged)]
152pub enum RequestParameters<ValueT = Value> {
153 ByPosition(Vec<ValueT>),
155 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#[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#[derive(Debug, Clone, PartialEq, Eq)]
298pub struct Response<ValueT = Value, ValueE = Value, StringE = String, IdT = Id> {
299 pub result: Result<ValueT, Error<ValueE, StringE>>,
310 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
419fn 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#[derive(Serialize, Debug, Clone, PartialEq, Eq, Deserialize)]
432pub struct Error<ValueT = Value, StringT = String> {
433 pub code: i64,
438 pub message: StringT,
441 #[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 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 PARSE_ERROR / parse_error = -32700;
517 INVALID_REQUEST / invalid_request = -32600;
519 METHOD_NOT_FOUND / method_not_found = -32601;
521 INVALID_PARAMS / invalid_params = -32602;
523 INTERNAL_ERROR / internal_error = -32603;
525}
526
527impl Error {
528 pub const SERVER_ERROR_RANGE: RangeInclusive<i64> = -32099..=-32000;
530}
531
532impl Error {
533 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#[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#[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}