1use std::borrow::Cow;
31use std::fmt;
32
33use serde::de::{self, Deserializer, Unexpected, Visitor};
34use serde::ser::Serializer;
35use serde::{Deserialize, Serialize};
36use serde_json::Value as JsonValue;
37
38use crate::error::{ErrorCode, INVALID_PARAMS_MSG};
39use crate::{ErrorObject, ErrorObjectOwned};
40
41#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
43pub struct TwoPointZero;
44
45struct TwoPointZeroVisitor;
46
47impl<'de> Visitor<'de> for TwoPointZeroVisitor {
48 type Value = TwoPointZero;
49
50 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
51 formatter.write_str(r#"a string "2.0""#)
52 }
53
54 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
55 where
56 E: de::Error,
57 {
58 match s {
59 "2.0" => Ok(TwoPointZero),
60 _ => Err(de::Error::invalid_value(Unexpected::Str(s), &self)),
61 }
62 }
63}
64
65impl<'de> Deserialize<'de> for TwoPointZero {
66 fn deserialize<D>(deserializer: D) -> Result<TwoPointZero, D::Error>
67 where
68 D: Deserializer<'de>,
69 {
70 deserializer.deserialize_str(TwoPointZeroVisitor)
71 }
72}
73
74impl Serialize for TwoPointZero {
75 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: Serializer,
78 {
79 serializer.serialize_str("2.0")
80 }
81}
82
83#[derive(Clone, Debug)]
89pub struct Params<'a>(Option<Cow<'a, str>>);
90
91impl<'a> Params<'a> {
92 pub fn new(raw: Option<&'a str>) -> Self {
94 Self(raw.map(|r| r.trim().into()))
95 }
96
97 pub fn is_object(&self) -> bool {
99 let json: &str = match self.0 {
100 Some(ref cow) => cow,
101 None => return false,
102 };
103 json.starts_with('{')
104 }
105
106 pub fn sequence(&self) -> ParamsSequence {
111 let json = match self.0.as_ref() {
112 Some(json) if json == "[]" => "",
114 Some(json) => json,
115 None => "",
116 };
117 ParamsSequence(json)
118 }
119
120 pub fn parse<T>(&'a self) -> Result<T, ErrorObjectOwned>
122 where
123 T: Deserialize<'a>,
124 {
125 let params = self.0.as_ref().map(AsRef::as_ref).unwrap_or("null");
127 serde_json::from_str(params).map_err(invalid_params)
128 }
129
130 pub fn one<T>(&'a self) -> Result<T, ErrorObjectOwned>
132 where
133 T: Deserialize<'a>,
134 {
135 self.parse::<[T; 1]>().map(|[res]| res)
136 }
137
138 pub fn into_owned(self) -> Params<'static> {
142 Params(self.0.map(|s| Cow::Owned(s.into_owned())))
143 }
144
145 pub fn len_bytes(&self) -> usize {
147 match self.0 {
148 Some(ref cow) => cow.len(),
149 None => 0,
150 }
151 }
152
153 pub fn as_str(&self) -> Option<&str> {
155 match self.0 {
156 Some(ref cow) => Some(cow.as_ref()),
157 None => None,
158 }
159 }
160}
161
162#[derive(Debug, Copy, Clone)]
170pub struct ParamsSequence<'a>(&'a str);
171
172impl<'a> ParamsSequence<'a> {
173 fn next_inner<T>(&mut self) -> Option<Result<T, ErrorObjectOwned>>
174 where
175 T: Deserialize<'a>,
176 {
177 let mut json = self.0;
178 match json.as_bytes().first()? {
179 b']' => {
180 self.0 = "";
181 return None;
182 }
183 b'[' | b',' => json = &json[1..],
184 _ => {
185 let errmsg = format!("Invalid params. Expected one of '[', ']' or ',' but found {json:?}");
186 return Some(Err(invalid_params(errmsg)));
187 }
188 }
189
190 let mut iter = serde_json::Deserializer::from_str(json).into_iter::<T>();
191
192 match iter.next()? {
193 Ok(value) => {
194 self.0 = json[iter.byte_offset()..].trim_start();
195
196 Some(Ok(value))
197 }
198 Err(e) => {
199 self.0 = "";
200 Some(Err(invalid_params(e)))
201 }
202 }
203 }
204
205 #[allow(clippy::should_implement_trait)]
221 pub fn next<T>(&mut self) -> Result<T, ErrorObjectOwned>
222 where
223 T: Deserialize<'a>,
224 {
225 match self.next_inner() {
226 Some(result) => result,
227 None => Err(invalid_params("No more params")),
228 }
229 }
230
231 pub fn optional_next<T>(&mut self) -> Result<Option<T>, ErrorObjectOwned>
250 where
251 T: Deserialize<'a>,
252 {
253 match self.next_inner::<Option<T>>() {
254 Some(result) => result,
255 None => Ok(None),
256 }
257 }
258}
259
260#[derive(Debug, PartialEq, Clone, Hash, Eq, Deserialize, Serialize)]
262#[serde(deny_unknown_fields)]
263#[serde(untagged)]
264pub enum SubscriptionId<'a> {
265 Num(u64),
267 #[serde(borrow)]
269 Str(Cow<'a, str>),
270}
271
272impl<'a> From<SubscriptionId<'a>> for JsonValue {
273 fn from(sub_id: SubscriptionId) -> Self {
274 match sub_id {
275 SubscriptionId::Num(n) => n.into(),
276 SubscriptionId::Str(s) => s.into_owned().into(),
277 }
278 }
279}
280
281impl<'a> From<u64> for SubscriptionId<'a> {
282 fn from(sub_id: u64) -> Self {
283 Self::Num(sub_id)
284 }
285}
286
287impl<'a> From<String> for SubscriptionId<'a> {
288 fn from(sub_id: String) -> Self {
289 Self::Str(sub_id.into())
290 }
291}
292
293impl<'a> TryFrom<JsonValue> for SubscriptionId<'a> {
294 type Error = ();
295
296 fn try_from(json: JsonValue) -> Result<SubscriptionId<'a>, ()> {
297 match json {
298 JsonValue::String(s) => Ok(SubscriptionId::Str(s.into())),
299 JsonValue::Number(n) => {
300 if let Some(n) = n.as_u64() {
301 Ok(SubscriptionId::Num(n))
302 } else {
303 Err(())
304 }
305 }
306 _ => Err(()),
307 }
308 }
309}
310
311impl<'a> SubscriptionId<'a> {
312 pub fn into_owned(self) -> SubscriptionId<'static> {
316 match self {
317 SubscriptionId::Num(num) => SubscriptionId::Num(num),
318 SubscriptionId::Str(s) => SubscriptionId::Str(Cow::Owned(s.into_owned())),
319 }
320 }
321}
322
323#[derive(Debug, thiserror::Error)]
325pub enum InvalidRequestId {
326 #[error("request ID={0} is not a pending call")]
328 NotPendingRequest(String),
329
330 #[error("request ID={0} is already occupied by a pending call")]
332 Occupied(String),
333
334 #[error("request ID={0} is invalid")]
336 Invalid(String),
337}
338
339#[derive(Debug, PartialEq, Clone, Hash, Eq, Deserialize, Serialize, PartialOrd, Ord)]
341#[serde(deny_unknown_fields)]
342#[serde(untagged)]
343pub enum Id<'a> {
344 Null,
346 Number(u64),
348 #[serde(borrow)]
350 Str(Cow<'a, str>),
351}
352
353impl<'a> Id<'a> {
354 pub fn as_number(&self) -> Option<&u64> {
356 match self {
357 Self::Number(n) => Some(n),
358 _ => None,
359 }
360 }
361
362 pub fn as_str(&self) -> Option<&str> {
364 match self {
365 Self::Str(s) => Some(s.as_ref()),
366 _ => None,
367 }
368 }
369
370 pub fn as_null(&self) -> Option<()> {
372 match self {
373 Self::Null => Some(()),
374 _ => None,
375 }
376 }
377
378 pub fn into_owned(self) -> Id<'static> {
382 match self {
383 Id::Null => Id::Null,
384 Id::Number(num) => Id::Number(num),
385 Id::Str(s) => Id::Str(Cow::Owned(s.into_owned())),
386 }
387 }
388
389 pub fn try_parse_inner_as_number(&self) -> Result<u64, InvalidRequestId> {
391 match self {
392 Id::Null => Err(InvalidRequestId::Invalid("null".to_string())),
393 Id::Number(num) => Ok(*num),
394 Id::Str(s) => s.parse().map_err(|_| InvalidRequestId::Invalid(s.as_ref().to_owned())),
395 }
396 }
397}
398
399impl<'a> std::fmt::Display for Id<'a> {
400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401 match self {
402 Id::Null => f.write_str("null"),
403 Id::Number(n) => f.write_str(&n.to_string()),
404 Id::Str(s) => f.write_str(s),
405 }
406 }
407}
408
409fn invalid_params(e: impl ToString) -> ErrorObjectOwned {
410 ErrorObject::owned(ErrorCode::InvalidParams.code(), INVALID_PARAMS_MSG, Some(e.to_string()))
411}
412
413#[cfg(test)]
414mod test {
415 use super::{Cow, Id, JsonValue, Params, SubscriptionId, TwoPointZero};
416 use crate::response::SubscriptionPayload;
417
418 #[test]
419 fn id_deserialization() {
420 let s = r#""2""#;
421 let deserialized: Id = serde_json::from_str(s).unwrap();
422 match deserialized {
423 Id::Str(ref cow) => {
424 assert!(matches!(cow, Cow::Borrowed(_)));
425 assert_eq!(cow, "2");
426 }
427 _ => panic!("Expected Id::Str"),
428 }
429
430 let s = r#"2"#;
431 let deserialized: Id = serde_json::from_str(s).unwrap();
432 assert_eq!(deserialized, Id::Number(2));
433
434 let s = r#""2x""#;
435 let deserialized: Id = serde_json::from_str(s).unwrap();
436 assert_eq!(deserialized, Id::Str(Cow::Borrowed("2x")));
437
438 let s = r#"[1337]"#;
439 assert!(serde_json::from_str::<Id>(s).is_err());
440
441 let s = r#"[null, 0, 2, "\"3"]"#;
442 let deserialized: Vec<Id> = serde_json::from_str(s).unwrap();
443 assert_eq!(deserialized, vec![Id::Null, Id::Number(0), Id::Number(2), Id::Str("\"3".into())]);
444 }
445
446 #[test]
447 fn id_serialization() {
448 let d =
449 vec![Id::Null, Id::Number(0), Id::Number(2), Id::Number(3), Id::Str("\"3".into()), Id::Str("test".into())];
450 let serialized = serde_json::to_string(&d).unwrap();
451 assert_eq!(serialized, r#"[null,0,2,3,"\"3","test"]"#);
452 }
453
454 #[test]
455 fn params_parse() {
456 let none = Params::new(None);
457 assert!(none.sequence().next::<u64>().is_err());
458 assert!(none.parse::<Option<u64>>().is_ok());
459 assert_eq!(none.len_bytes(), 0);
460
461 let array_params = Params::new(Some("[1, 2, 3]"));
462 assert_eq!(array_params.len_bytes(), 9);
463 let arr: Result<[u64; 3], _> = array_params.parse();
464 assert!(arr.is_ok());
465
466 let mut seq = array_params.sequence();
467
468 assert_eq!(seq.next::<u64>().unwrap(), 1);
469 assert_eq!(seq.next::<u64>().unwrap(), 2);
470 assert_eq!(seq.next::<u64>().unwrap(), 3);
471 assert!(seq.next::<u64>().is_err());
472
473 let array_one = Params::new(Some("[1]"));
474 assert_eq!(array_one.len_bytes(), 3);
475 let one: Result<u64, _> = array_one.one();
476 assert!(one.is_ok());
477
478 let object_params = Params::new(Some(r#"{"beef":99,"dinner":0}"#));
479 assert_eq!(object_params.len_bytes(), 22);
480 let obj: Result<JsonValue, _> = object_params.parse();
481 assert!(obj.is_ok());
482 }
483
484 #[test]
485 fn params_parse_empty_json() {
486 let array_params = Params::new(Some("[]"));
487 let arr: Result<Vec<u64>, _> = array_params.parse();
488 assert!(arr.is_ok());
489
490 let obj_params = Params::new(Some("{}"));
491 let obj: Result<JsonValue, _> = obj_params.parse();
492 assert!(obj.is_ok());
493 }
494
495 #[test]
496 fn params_sequence_borrows() {
497 let params = Params::new(Some(r#"["foo", "bar"]"#));
498 let mut seq = params.sequence();
499
500 assert_eq!(seq.next::<&str>().unwrap(), "foo");
501 assert_eq!(seq.next::<&str>().unwrap(), "bar");
502 assert!(seq.next::<&str>().is_err());
503
504 let params: (&str, &str) = params.parse().unwrap();
506 assert_eq!(params, ("foo", "bar"));
507 }
508
509 #[test]
510 fn two_point_zero_serde_works() {
511 let initial_ser = r#""2.0""#;
512 let two_point_zero: TwoPointZero = serde_json::from_str(initial_ser).unwrap();
514 let serialized = serde_json::to_string(&two_point_zero).unwrap();
515 assert_eq!(serialized, initial_ser);
516 }
517
518 #[test]
519 fn subscription_id_serde_works() {
520 let test_vector = &[("42", SubscriptionId::Num(42)), (r#""one""#, SubscriptionId::Str("one".into()))];
521
522 for (initial_ser, expected) in test_vector {
523 let id: SubscriptionId = serde_json::from_str(initial_ser).unwrap();
524 assert_eq!(&id, expected);
525 let serialized = serde_json::to_string(&id).unwrap();
526 assert_eq!(&serialized, initial_ser);
527 }
528 }
529
530 #[test]
531 fn subscription_params_serialize_work() {
532 let ser = serde_json::to_string(&SubscriptionPayload { subscription: SubscriptionId::Num(12), result: "goal" })
533 .unwrap();
534 let exp = r#"{"subscription":12,"result":"goal"}"#;
535 assert_eq!(ser, exp);
536 }
537
538 #[test]
539 fn subscription_params_deserialize_work() {
540 let ser = r#"{"subscription":"9","result":"offside"}"#;
541 assert!(
542 serde_json::from_str::<SubscriptionPayload<()>>(ser).is_err(),
543 "invalid type should not be deserializable"
544 );
545 let dsr: SubscriptionPayload<JsonValue> = serde_json::from_str(ser).unwrap();
546 assert_eq!(dsr.subscription, SubscriptionId::Str("9".into()));
547 assert_eq!(dsr.result, serde_json::json!("offside"));
548 }
549
550 #[test]
551 fn params_sequence_optional_ignore_empty() {
552 let params = Params::new(Some(r#"["foo", "bar"]"#));
553 let mut seq = params.sequence();
554
555 assert_eq!(seq.optional_next::<&str>().unwrap(), Some("foo"));
556 assert_eq!(seq.optional_next::<&str>().unwrap(), Some("bar"));
557
558 let params = Params::new(Some(r#"[]"#));
559 let mut seq = params.sequence();
560 assert!(seq.optional_next::<&str>().unwrap().is_none());
561
562 let params = Params::new(Some(r#" [] "#));
563 let mut seq = params.sequence();
564 assert!(seq.optional_next::<&str>().unwrap().is_none());
565
566 let params = Params::new(Some(r#"{}"#));
567 let mut seq = params.sequence();
568 assert!(seq.optional_next::<&str>().is_err(), "JSON object not supported by RpcSequence");
569
570 let params = Params::new(Some(r#"[12, "[]", [], {}]"#));
571 let mut seq = params.sequence();
572 assert_eq!(seq.optional_next::<u64>().unwrap(), Some(12));
573 assert_eq!(seq.optional_next::<&str>().unwrap(), Some("[]"));
574 assert_eq!(seq.optional_next::<Vec<u8>>().unwrap(), Some(vec![]));
575 assert_eq!(seq.optional_next::<serde_json::Value>().unwrap(), Some(serde_json::json!({})));
576 }
577
578 #[test]
579 fn params_sequence_optional_nesting_works() {
580 let nested = Params::new(Some(r#"[1, [2], [3, 4], [[5], [6,7], []], {"named":7}]"#));
581 let mut seq = nested.sequence();
582 assert_eq!(seq.optional_next::<i8>().unwrap(), Some(1));
583 assert_eq!(seq.optional_next::<[i8; 1]>().unwrap(), Some([2]));
584 assert_eq!(seq.optional_next::<Vec<u16>>().unwrap(), Some(vec![3, 4]));
585 assert_eq!(seq.optional_next::<Vec<Vec<u32>>>().unwrap(), Some(vec![vec![5], vec![6, 7], vec![]]));
586 assert_eq!(seq.optional_next::<serde_json::Value>().unwrap(), Some(serde_json::json!({"named":7})));
587 }
588}