1#![deny(missing_docs)]
187
188const SERIALZATION_ERROR: i64 = -32000;
189
190pub use easy_jsonrpc_proc_macro_mwc::rpc;
191
192#[doc(hidden)]
194pub use jsonrpc_core::types::{
195 self, Error, ErrorCode, Failure, Id, MethodCall, Notification, Output, Success, Version,
196};
197#[doc(hidden)]
198use serde::de::Deserialize;
199#[doc(hidden)]
200pub use serde_json::{self, Value};
201
202use rand;
203use serde::ser::Serialize;
204use serde_json::json;
205use std::{collections::BTreeMap, marker::PhantomData};
206
207pub trait Handler {
209 fn handle(&self, method: &str, params: Params) -> Result<Value, jsonrpc_core::Error>;
212
213 fn handle_request(&self, raw_request: Value) -> MaybeReply {
215 let request: jsonrpc_core::Request = match serde_json::from_value(raw_request) {
216 Ok(request) => request,
217 Err(_) => {
218 return MaybeReply::Reply(serde_json::json!({
219 "jsonrpc": "2.0",
220 "error": {
221 "code": -32700,
222 "message": "Parse error"
223 },
224 "id": null
225 }));
226 }
227 };
228 let response = match handle_parsed_request(self, request) {
229 Some(ret) => ret,
230 None => return MaybeReply::DontReply,
231 };
232 MaybeReply::Reply(serde_json::to_value(response).unwrap_or_else(|e| {
233 serde_json::json!({
234 "jsonrpc": "2.0",
235 "error": {
236 "code": SERIALZATION_ERROR,
237 "message": "Serialization error",
238 "data": format!("{}", e),
239 },
240 "id": null
241 })
242 }))
243 }
244}
245
246#[derive(Clone, PartialEq, Debug)]
248pub enum MaybeReply {
249 Reply(Value),
251 DontReply,
253}
254
255impl MaybeReply {
256 pub fn as_option(self) -> Option<Value> {
258 match self {
259 MaybeReply::Reply(val) => Some(val),
260 MaybeReply::DontReply => None,
261 }
262 }
263}
264
265fn handle_call<S: ?Sized + Handler>(slef: &S, call: jsonrpc_core::Call) -> Option<Output> {
270 let (method, params, maybe_id, version): (
271 String,
272 jsonrpc_core::Params,
273 Option<Id>,
274 Option<Version>,
275 ) = match call {
276 jsonrpc_core::Call::Invalid { id } => {
277 return Some(Output::invalid_request(id, None));
278 }
279 jsonrpc_core::Call::MethodCall(MethodCall {
280 method,
281 params,
282 id,
283 jsonrpc,
284 }) => (method, params, Some(id), jsonrpc),
285 jsonrpc_core::Call::Notification(Notification {
286 method,
287 params,
288 jsonrpc,
289 }) => (method, params, None, jsonrpc),
290 };
291 let args = Params::from_rc_params(params);
292 let ret = slef.handle(&method, args);
293 let id = maybe_id?;
294 Some(match ret {
295 Ok(ok) => Output::Success(Success {
296 jsonrpc: version,
297 result: ok,
298 id,
299 }),
300 Err(err) => Output::Failure(Failure {
301 jsonrpc: version,
302 error: err,
303 id,
304 }),
305 })
306}
307
308fn handle_parsed_request<S: ?Sized + Handler>(
311 slef: &S,
312 request: jsonrpc_core::Request,
313) -> Option<jsonrpc_core::Response> {
314 match request {
315 jsonrpc_core::Request::Single(call) => {
316 handle_call(slef, call).map(jsonrpc_core::Response::Single)
317 }
318 jsonrpc_core::Request::Batch(mut calls) => {
319 let outputs = calls
320 .drain(..)
321 .filter_map(|call| handle_call(slef, call))
322 .collect::<Vec<_>>();
323 if outputs.is_empty() {
324 None
325 } else {
326 Some(jsonrpc_core::Response::Batch(outputs))
327 }
328 }
329 }
330}
331
332#[doc(hidden)]
333#[derive(
334 Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, serde::Serialize, serde::Deserialize,
335)]
336pub enum InvalidArgs {
337 WrongNumberOfArgs { expected: usize, actual: usize },
338 ExtraNamedParameter { name: String },
339 MissingNamedParameter { name: &'static str },
340 InvalidArgStructure { name: &'static str, index: usize },
341}
342
343impl Into<Error> for InvalidArgs {
344 fn into(self) -> Error {
345 match self {
346 InvalidArgs::WrongNumberOfArgs { expected, actual } => Error::invalid_params(format!(
347 "WrongNumberOfArgs. Expected {}. Actual {}",
348 expected, actual
349 )),
350 InvalidArgs::ExtraNamedParameter { name } => {
351 Error::invalid_params(format!("ExtraNamedParameter {}", name))
352 }
353 InvalidArgs::MissingNamedParameter { name } => {
354 Error::invalid_params(format!("MissingNamedParameter {}", name))
355 }
356 InvalidArgs::InvalidArgStructure { name, index } => Error::invalid_params(format!(
357 "InvalidArgStructure {} at position {}.",
358 name, index
359 )),
360 }
361 }
362}
363
364#[derive(Debug)]
369pub enum Params {
370 Positional(Vec<Value>),
373 Named(serde_json::Map<String, Value>),
375}
376
377impl Params {
378 fn from_rc_params(params: jsonrpc_core::Params) -> Self {
379 match params {
380 jsonrpc_core::Params::Array(arr) => Params::Positional(arr),
381 jsonrpc_core::Params::Map(map) => Params::Named(map),
382 jsonrpc_core::Params::None => Params::Positional(vec![]),
383 }
384 }
385
386 pub fn get_rpc_args(self, names: &[&'static str]) -> Result<Vec<Value>, InvalidArgs> {
394 debug_assert!(
395 {
396 fn contains_duplicates(list: &[&str]) -> bool {
397 (1..list.len()).any(|i| list[i..].contains(&list[i - 1]))
398 }
399 !contains_duplicates(names)
400 },
401 "get_rpc_args recieved duplicate argument names"
402 );
403 let ar: Vec<Value> = match self {
404 Params::Positional(ar) => ar,
405 Params::Named(mut ma) => {
406 let mut ar: Vec<Value> = Vec::with_capacity(names.len());
407 for name in names.iter() {
408 ar.push(ma.remove(*name).unwrap_or( Value::Null ));
409 }
410 debug_assert_eq!(ar.len(), names.len());
411 match ma.keys().next() {
412 Some(key) => {
413 return Err(InvalidArgs::ExtraNamedParameter { name: key.clone() })
414 }
415 None => ar,
416 }
417 }
418 };
419 if ar.len() != names.len() {
420 Err(InvalidArgs::WrongNumberOfArgs {
421 expected: names.len(),
422 actual: ar.len(),
423 })
424 } else {
425 Ok(ar)
426 }
427 }
428}
429
430#[derive(Debug)]
435pub struct BoundMethod<'a, T>
436where
437 T: Deserialize<'static>,
438{
439 method: &'a str,
440 args: Vec<Value>,
441 _spook: PhantomData<*const T>,
442}
443
444impl<'a, T> BoundMethod<'a, T>
445where
446 T: Deserialize<'static>,
447{
448 pub fn new(method: &'a str, args: Vec<Value>) -> BoundMethod<'a, T> {
452 BoundMethod {
453 method,
454 args,
455 _spook: PhantomData,
456 }
457 }
458
459 pub fn call(&'a self) -> (Call<'a>, Tracker<T>)
461 where
462 T: Deserialize<'static>,
463 {
464 let Self { method, args, .. } = self;
465 let id = rand::random::<u64>();
466 (
467 Call {
468 method,
469 args,
470 id: Some(id),
471 },
472 Tracker {
473 id,
474 _spook: PhantomData,
475 },
476 )
477 }
478
479 pub fn notification(&'a self) -> Call<'a> {
482 let Self { method, args, .. } = self;
483 Call {
484 method,
485 args,
486 id: None,
487 }
488 }
489}
490
491pub struct Call<'a> {
497 method: &'a str,
498 args: &'a [Value],
499 id: Option<u64>,
500}
501
502impl<'a> Call<'a> {
503 pub fn as_request(&self) -> Value {
505 let Self { method, id, args } = self;
506 match id {
507 Some(id) => json!({
508 "jsonrpc": "2.0",
509 "method": method,
510 "params": args,
511 "id": id,
512 }),
513 None => json!({
514 "jsonrpc": "2.0",
515 "method": method,
516 "params": args,
517 }),
518 }
519 }
520
521 pub fn batch_request(calls: &[Self]) -> Value {
523 debug_assert!({
524 fn contains_duplicates(list: &[u64]) -> bool {
525 (1..list.len()).any(|i| list[i..].contains(&list[i - 1]))
526 }
527 let ids = calls.iter().filter_map(|call| call.id).collect::<Vec<_>>();
528 !contains_duplicates(ids.as_slice())
529 });
530 Value::Array(calls.iter().map(Call::as_request).collect())
531 }
532}
533
534#[doc(hidden)]
536pub fn try_serialize<T: Serialize>(t: &T) -> Result<Value, Error> {
537 serde_json::to_value(t).map_err(|e| Error {
541 code: ErrorCode::ServerError(SERIALZATION_ERROR),
542 message: "Serialization error".to_owned(),
543 data: Some(Value::String(format!("{}", e))),
544 })
545}
546
547#[derive(Clone, PartialEq, Debug)]
549pub enum ResponseFail {
550 ResultNotFound,
552 InvalidResponse,
554 RpcError(Error),
556}
557
558#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
562pub struct ArgSerializeError;
563
564#[derive(Clone, PartialEq, Debug)]
566pub enum InvalidResponse {
567 DeserailizeFailure,
569 ContainsNonNumericId,
572}
573
574pub struct Response {
577 pub outputs: BTreeMap<u64, Result<Value, Error>>,
579}
580
581impl Response {
582 pub fn from_json_response(raw_jsonrpc_response: Value) -> Result<Self, InvalidResponse> {
584 let response: jsonrpc_core::Response = serde_json::from_value(raw_jsonrpc_response)
585 .map_err(|_| InvalidResponse::DeserailizeFailure)?;
586 let mut calls: Vec<Output> = match response {
587 jsonrpc_core::Response::Single(out) => vec![out],
588 jsonrpc_core::Response::Batch(outs) => outs,
589 };
590 debug_assert!({
591 fn contains_duplicates(list: &[u64]) -> bool {
592 (1..list.len()).any(|i| list[i..].contains(&list[i - 1]))
593 }
594 let ids = calls
595 .iter()
596 .filter_map(|out| match out {
597 Output::Success(Success {
598 id: Id::Num(id), ..
599 })
600 | Output::Failure(Failure {
601 id: Id::Num(id), ..
602 }) => Some(*id),
603 _ => None,
604 })
605 .collect::<Vec<_>>();
606 !contains_duplicates(ids.as_slice())
607 });
608 let outputs = calls
609 .drain(..)
610 .map(
611 |out| -> Result<(u64, Result<Value, Error>), InvalidResponse> {
612 match out {
613 Output::Success(Success {
614 result,
615 id: Id::Num(id),
616 ..
617 }) => Ok((id, Ok(result))),
618 Output::Failure(Failure {
619 error,
620 id: Id::Num(id),
621 ..
622 }) => Ok((id, Err(error))),
623 _ => Err(InvalidResponse::ContainsNonNumericId),
624 }
625 },
626 )
627 .collect::<Result<BTreeMap<u64, Result<Value, Error>>, InvalidResponse>>()?;
628 Ok(Self { outputs })
629 }
630
631 pub fn remove(&mut self, id: u64) -> Option<Result<Value, Error>> {
633 self.outputs.remove(&id)
634 }
635}
636
637pub struct Tracker<T>
640where
641 T: Deserialize<'static>,
642{
643 id: u64,
644 _spook: PhantomData<*const T>,
645}
646
647impl<T> Tracker<T>
648where
649 T: Deserialize<'static>,
650{
651 pub fn get_return(&self, response: &mut Response) -> Result<T, ResponseFail> {
655 let result = response
656 .remove(self.id)
657 .ok_or(ResponseFail::ResultNotFound)?;
658 let raw_return = result.map_err(ResponseFail::RpcError)?;
659 <T>::deserialize(raw_return).map_err(|_| ResponseFail::InvalidResponse)
660 }
661}
662
663#[cfg(test)]
664mod test {
665 mod easy_jsonrpc_mwc {
666 pub use crate::*;
667 }
668 use super::{Handler, InvalidArgs, MaybeReply, Params};
669 use jsonrpc_core;
670 use serde_json::{json, Value};
671
672 #[easy_jsonrpc_mwc::rpc]
673 pub trait Adder {
674 fn checked_add(&self, a: isize, b: isize) -> Option<isize>;
675 fn wrapping_add(&self, a: isize, b: isize) -> isize;
676 fn greet(&self) -> String;
677 fn swallow(&self);
678 fn repeat_list(&self, lst: Vec<usize>) -> Vec<usize>;
679 fn fail(&self) -> Result<isize, String>;
680 fn succeed(&self) -> Result<isize, String>;
681 fn echo_ref(&self, a: &isize) -> isize;
682 }
683
684 struct AdderImpl;
685 impl Adder for AdderImpl {
686 fn checked_add(&self, a: isize, b: isize) -> Option<isize> {
687 a.checked_add(b)
688 }
689
690 fn wrapping_add(&self, a: isize, b: isize) -> isize {
691 a.wrapping_add(b)
692 }
693
694 fn greet(&self) -> String {
695 "hello".into()
696 }
697
698 fn swallow(&self) {}
699
700 fn repeat_list(&self, lst: Vec<usize>) -> Vec<usize> {
701 let mut ret = lst.clone();
702 ret.extend(lst);
703 ret
704 }
705
706 fn fail(&self) -> Result<isize, String> {
707 Err("tada!".into())
708 }
709
710 fn succeed(&self) -> Result<isize, String> {
711 Ok(1)
712 }
713
714 fn echo_ref(&self, a: &isize) -> isize {
715 *a
716 }
717 }
718
719 fn assert_adder_response(request: Value, response: Value) {
720 assert_eq!(
721 (&AdderImpl {} as &dyn Adder)
722 .handle_request(request)
723 .as_option()
724 .unwrap(),
725 response
726 );
727 }
728
729 fn error_code(request: Value) -> jsonrpc_core::ErrorCode {
730 let raw_response = (&AdderImpl {} as &dyn Adder)
731 .handle_request(request)
732 .as_option()
733 .unwrap();
734 let response: jsonrpc_core::Response = serde_json::from_value(raw_response).unwrap();
735 match response {
736 jsonrpc_core::Response::Single(jsonrpc_core::Output::Failure(
737 jsonrpc_core::Failure { error, .. },
738 )) => error.code,
739 _ => panic!(),
740 }
741 }
742
743 #[test]
744 fn batch() {
745 assert_adder_response(
746 json!([
747 {
748 "jsonrpc": "2.0",
749 "method": "wrapping_add",
750 "params": [1, 1],
751 "id": 1
752 },
753 {
754 "jsonrpc": "2.0",
755 "method": "wrapping_add",
756 "params": [1, 2],
757 "id": 2
758 },
759 {
760 "jsonrpc": "2.0",
761 "method": "wrapping_add",
762 "params": [1, 3],
763 "id": null
764 },
765 {
766 "jsonrpc": "2.0",
767 "method": "wrapping_add",
768 "params": [1, 4],
769 },
770 ]),
771 json!([
772 {
773 "jsonrpc": "2.0",
774 "result": 2,
775 "id": 1
776 },
777 {
778 "jsonrpc": "2.0",
779 "result": 3,
780 "id": 2
781 },
782 {
783 "jsonrpc": "2.0",
784 "result": 4,
785 "id": null
786 }
787 ]),
788 );
789 }
790
791 #[test]
792 fn positional_args() {
793 assert_adder_response(
794 json!({
795 "jsonrpc": "2.0",
796 "method": "wrapping_add",
797 "params": [1, 1],
798 "id": 1
799 }),
800 json!({
801 "jsonrpc": "2.0",
802 "result": 2,
803 "id": 1
804 }),
805 );
806 }
807
808 #[test]
809 fn string_id() {
810 assert_adder_response(
811 json!({
812 "jsonrpc": "2.0",
813 "method": "wrapping_add",
814 "params": [1, 1],
815 "id": "jfjfks sasdfk"
816 }),
817 json!({
818 "jsonrpc": "2.0",
819 "result": 2,
820 "id": "jfjfks sasdfk"
821 }),
822 );
823 assert_adder_response(
824 json!({
825 "jsonrpc": "2.0",
826 "method": "wrapping_add",
827 "params": [1, 1],
828 "id": ""
829 }),
830 json!({
831 "jsonrpc": "2.0",
832 "result": 2,
833 "id": ""
834 }),
835 );
836 }
837
838 #[test]
839 fn named_args() {
840 assert_adder_response(
841 json!({
842 "jsonrpc": "2.0",
843 "method": "wrapping_add",
844 "params": {
845 "a": 1,
846 "b": 1
847 },
848 "id": 1
849 }),
850 json!({
851 "jsonrpc": "2.0",
852 "result": 2,
853 "id": 1
854 }),
855 );
856 }
857
858 #[test]
859 fn null_args() {
860 let response = json!({
861 "jsonrpc": "2.0",
862 "result": "hello",
863 "id": 1
864 });
865 assert_adder_response(
866 json!({
867 "jsonrpc": "2.0",
868 "method": "greet",
869 "params": {},
870 "id": 1
871 }),
872 response.clone(),
873 );
874 assert_adder_response(
875 json!({
876 "jsonrpc": "2.0",
877 "method": "greet",
878 "params": [],
879 "id": 1
880 }),
881 response.clone(),
882 );
883 assert_adder_response(
884 json!({
885 "jsonrpc": "2.0",
886 "method": "greet",
887 "params": null,
888 "id": 1
889 }),
890 response.clone(),
891 );
892 assert_adder_response(
893 json!({
894 "jsonrpc": "2.0",
895 "method": "greet",
896 "id": 1
897 }),
898 response.clone(),
899 );
900 }
901
902 #[test]
903 fn null_return() {
904 assert_adder_response(
905 json!({
906 "jsonrpc": "2.0",
907 "method": "swallow",
908 "params": [],
909 "id": 1
910 }),
911 json!({
912 "jsonrpc": "2.0",
913 "result": null,
914 "id": 1
915 }),
916 );
917 }
918
919 #[test]
920 fn incorrect_method_name() {
921 assert_eq!(
922 error_code(json!({
923 "jsonrpc": "2.0",
924 "method": "nonexist",
925 "params": [],
926 "id": 1
927 })),
928 jsonrpc_core::ErrorCode::MethodNotFound,
929 );
930 }
931
932 #[test]
933 fn incorrect_args() {
934 assert_eq!(
935 error_code(json!({
936 "jsonrpc": "2.0",
937 "method": "wrapping_add",
938 "params": [],
939 "id": 1
940 })),
941 jsonrpc_core::ErrorCode::InvalidParams,
942 );
943 assert_eq!(
944 error_code(json!({
945 "jsonrpc": "2.0",
946 "method": "wrapping_add",
947 "params": {
948 "notanarg": 1,
949 "notarg": 1
950 },
951 "id": 1
952 })),
953 jsonrpc_core::ErrorCode::InvalidParams,
954 );
955 assert_eq!(
956 error_code(json!({
957 "jsonrpc": "2.0",
958 "method": "wrapping_add",
959 "params": [[], []],
960 "id": 1
961 })),
962 jsonrpc_core::ErrorCode::InvalidParams,
963 );
964 }
965
966 #[test]
967 fn complex_type() {
968 assert_adder_response(
969 json!({
970 "jsonrpc": "2.0",
971 "method": "repeat_list",
972 "params": [[1, 2, 3]],
973 "id": 1
974 }),
975 json!({
976 "jsonrpc": "2.0",
977 "result": [1, 2, 3, 1, 2, 3],
978 "id": 1
979 }),
980 );
981 assert_eq!(
982 error_code(json!({
983 "jsonrpc": "2.0",
984 "method": "repeat_list",
985 "params": [[1], [12]],
986 "id": 1
987 }),),
988 jsonrpc_core::ErrorCode::InvalidParams,
989 );
990 assert_adder_response(
991 json!({
992 "jsonrpc": "2.0",
993 "method": "fail",
994 "params": [],
995 "id": 1
996 }),
997 json!({
998 "jsonrpc": "2.0",
999 "result": {
1000 "Err": "tada!"
1001 },
1002 "id": 1
1003 }),
1004 );
1005 assert_adder_response(
1006 json!({
1007 "jsonrpc": "2.0",
1008 "method": "succeed",
1009 "params": [],
1010 "id": 1
1011 }),
1012 json!({
1013 "jsonrpc": "2.0",
1014 "result": {
1015 "Ok": 1
1016 },
1017 "id": 1
1018 }),
1019 );
1020 }
1021
1022 #[test]
1023 fn notification() {
1024 let request = json!({
1025 "jsonrpc": "2.0",
1026 "method": "succeed",
1027 "params": []
1028 });
1029 assert_eq!(
1030 (&AdderImpl {} as &dyn Adder).handle_request(request),
1031 MaybeReply::DontReply
1032 );
1033 }
1034
1035 #[test]
1036 fn adder_client_non_macro() {
1037 #[easy_jsonrpc_mwc::rpc]
1038 trait Adder {
1039 fn checked_add(&self, a: usize, b: usize) -> Option<usize> {
1040 a.checked_add(b)
1041 }
1042 }
1043
1044 #[allow(non_camel_case_types)]
1045 pub enum adder_client {}
1046 impl adder_client {
1047 fn checked_add(
1048 arg0: usize,
1049 arg1: usize,
1050 ) -> Result<
1051 easy_jsonrpc_mwc::BoundMethod<'static, Option<usize>>,
1052 easy_jsonrpc_mwc::ArgSerializeError,
1053 > {
1054 Ok(easy_jsonrpc_mwc::BoundMethod::new(
1055 "checked_add",
1056 vec![
1057 serde_json::to_value(arg0).map_err(|_| easy_jsonrpc_mwc::ArgSerializeError)?,
1058 serde_json::to_value(arg1).map_err(|_| easy_jsonrpc_mwc::ArgSerializeError)?,
1059 ],
1060 ))
1061 }
1062 }
1063
1064 impl Adder for () {}
1065 let handler = &() as &dyn Adder;
1066
1067 let bind = adder_client::checked_add(1, 2).unwrap();
1068 let (call, tracker) = bind.call();
1069 let raw_response = handler
1070 .handle_request(call.as_request())
1071 .as_option()
1072 .unwrap();
1073 let mut response = easy_jsonrpc_mwc::Response::from_json_response(raw_response).unwrap();
1074 let result: Option<usize> = tracker.get_return(&mut response).unwrap();
1075 assert_eq!(result, Some(3));
1076
1077 assert_eq!(
1078 handler.handle_request(
1079 adder_client::checked_add(1, 2)
1080 .unwrap()
1081 .notification()
1082 .as_request()
1083 ),
1084 MaybeReply::DontReply
1085 );
1086 }
1087
1088 #[test]
1089 fn adder_client_with_macro() {
1090 #[easy_jsonrpc_mwc::rpc]
1091 trait Adder {
1092 fn checked_add(&self, a: usize, b: usize) -> Option<usize> {
1093 a.checked_add(b)
1094 }
1095 }
1096
1097 impl Adder for () {}
1098 let handler = &() as &dyn Adder;
1099
1100 let bind = adder::checked_add(1, 2).unwrap();
1101 let (call, tracker) = bind.call();
1102 let raw_response = handler
1103 .handle_request(call.as_request())
1104 .as_option()
1105 .unwrap();
1106 let mut response = easy_jsonrpc_mwc::Response::from_json_response(raw_response).unwrap();
1107 let result: Option<usize> = tracker.get_return(&mut response).unwrap();
1108 assert_eq!(result, Some(3));
1109
1110 let call = adder::checked_add(1, 2).unwrap();
1111 assert_eq!(
1112 handler.handle_request(call.notification().as_request()),
1113 MaybeReply::DontReply
1114 );
1115 }
1116
1117 #[test]
1118 fn client_with_reference_args() {
1119 let handler = &AdderImpl {} as &dyn Adder;
1120
1121 let bind = adder::echo_ref(&2).unwrap();
1122 let (call, tracker) = bind.call();
1123 let raw_response = handler
1124 .handle_request(call.as_request())
1125 .as_option()
1126 .unwrap();
1127 let mut response = easy_jsonrpc_mwc::Response::from_json_response(raw_response).unwrap();
1128 assert_eq!(tracker.get_return(&mut response).unwrap(), 2);
1129
1130 let call = adder::echo_ref(&2).unwrap();
1131 assert_eq!(
1132 handler.handle_request(call.notification().as_request()),
1133 MaybeReply::DontReply
1134 );
1135 }
1136
1137 #[test]
1138 fn response_double_get() {
1139 let handler = &AdderImpl as &dyn Adder;
1140 use easy_jsonrpc_mwc::Call;
1141 let bind0 = adder::checked_add(0, 0).unwrap();
1142 let (call0, tracker0) = bind0.call();
1143 let bind1 = adder::checked_add(1, 0).unwrap();
1144 let (call1, tracker1) = bind1.call();
1145 let bind2 = adder::wrapping_add(1, 1).unwrap();
1146 let (call2, tracker2) = bind2.call();
1147 let json_request = Call::batch_request(&[call0, call1, call2]);
1148 let json_response = handler.handle_request(json_request).as_option().unwrap();
1149 let mut response = easy_jsonrpc_mwc::Response::from_json_response(json_response).unwrap();
1150 assert_eq!(tracker0.get_return(&mut response).unwrap(), Some(0));
1151 assert_eq!(tracker2.get_return(&mut response).unwrap(), 2);
1152
1153 assert_eq!(tracker1.get_return(&mut response), Ok(Some(1)));
1155 assert_eq!(
1156 tracker1.get_return(&mut response),
1157 Err(easy_jsonrpc_mwc::ResponseFail::ResultNotFound)
1158 );
1159 }
1160
1161 #[test]
1162 fn local_types() {
1163 #[derive(serde::Serialize, serde::Deserialize)]
1164 pub struct Foo;
1165
1166 #[easy_jsonrpc_mwc::rpc]
1167 trait Bar {
1168 fn frob(&self) -> Foo;
1169 fn borf(&self, foo: Foo);
1170 }
1171 }
1172
1173 #[test]
1175 fn wrong_num_arg_err() {
1176 assert_adder_response(
1177 json!({
1178 "jsonrpc": "2.0",
1179 "method": "checked_add",
1180 "params": [1],
1181 "id": 1
1182 }),
1183 json!({
1184 "error": {
1185 "code": -32602,
1186 "message": "WrongNumberOfArgs. Expected 2. Actual 1"
1187 },
1188 "id": 1,
1189 "jsonrpc": "2.0"
1190 }),
1191 );
1192
1193 let res = Params::from_rc_params(jsonrpc_core::Params::Array(vec![
1194 json!(1),
1195 json!(2),
1196 json!(3),
1197 ]))
1198 .get_rpc_args(&["arg_one", "arg_two"]);
1199 assert_eq!(
1200 res,
1201 Err(InvalidArgs::WrongNumberOfArgs {
1202 expected: 2,
1203 actual: 3
1204 })
1205 );
1206 }
1207}