jsonrpc/
method_types.rs

1// Copyright 2016 Bruno Medeiros
2//
3// Licensed under the Apache License, Version 2.0 
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>. 
5// This file may not be copied, modified, or distributed
6// except according to those terms.
7
8
9//use util::core::*;
10
11use serde;
12use serde_json;
13
14use jsonrpc_common::*;
15use jsonrpc_response::*;
16
17/* -----------------  ----------------- */
18
19#[derive(Debug, PartialEq)]
20pub struct MethodError<DATA> {
21    pub code: u32,
22    pub message: String,
23    pub data: DATA
24}
25
26impl<DATA> MethodError<DATA> {
27    pub fn new(code: u32, msg: String, data : DATA) -> Self {
28        MethodError::<DATA> { code : code, message : msg, data : data }
29    }
30}
31
32pub type MethodResult<RETURN_VALUE, ERROR_DATA> = Result<RETURN_VALUE, MethodError<ERROR_DATA>>;
33
34
35impl<RET, RET_ERROR> From<MethodResult<RET, RET_ERROR>> for ResponseResult
36where 
37    RET : serde::Serialize, 
38    RET_ERROR : serde::Serialize,
39{
40    fn from(method_result: MethodResult<RET, RET_ERROR>) -> Self 
41    {
42        match method_result {
43            Ok(ret) => {
44                ResponseResult::Result(serde_json::to_value(&ret)) 
45            } 
46            Err(error) => {
47                let code : u32 = error.code;
48                let request_error = RequestError { 
49                    code : code as i64, // Safe convertion. TODO: use TryFrom when it's stable
50                    message : error.message,
51                    data : Some(serde_json::to_value(&error.data)),
52                };
53                ResponseResult::Error(request_error)
54            }
55        }
56    }
57}
58
59#[derive(Debug, PartialEq)]
60pub enum RequestResult<RET, RET_ERROR> {
61    MethodResult(MethodResult<RET, RET_ERROR>),
62    RequestError(RequestError),
63}
64
65impl<RET, RET_ERROR> RequestResult<RET, RET_ERROR> {
66    pub fn unwrap_result(self) -> MethodResult<RET, RET_ERROR> {
67        match self {
68        	RequestResult::MethodResult(method_result) => method_result,
69        	_ => panic!("Expected a RequestResult::MethodResult")
70        }
71    }
72    
73    pub fn unwrap_error(self) -> RequestError {
74        match self {
75        	RequestResult::RequestError(request_error) => request_error, 
76        	_ => panic!("Expected a RequestResult::RequestError")
77        }
78    }
79}
80
81impl<
82    RET : serde::Deserialize, 
83    RET_ERROR : serde::Deserialize, 
84> From<ResponseResult> for RequestResult<RET, RET_ERROR> 
85{
86    fn from(response_result : ResponseResult) -> Self 
87    {
88        match response_result {
89            ResponseResult::Result(result_value) => { 
90                let result : Result<RET, _> = serde_json::from_value(result_value);
91                match result {
92                    Ok(ok) => { 
93                        RequestResult::MethodResult(Ok(ok)) 
94                    }
95                    Err(error) => { 
96                        RequestResult::RequestError(error_JSON_RPC_InvalidResponse(error))
97                    }
98                }
99            } 
100            ResponseResult::Error(error) => {
101                RequestResult::RequestError(error)
102            }
103        }
104    }
105}
106
107    #[test]
108    fn test__RequestResult_from() {
109        use tests_sample_types::*;
110        
111        // Test JSON RPC error
112        let error = error_JSON_RPC_InvalidParams(r#"RPC_ERROR"#);
113        let response_result = ResponseResult::Error(error.clone());
114        assert_eq!(
115            RequestResult::<Point, ()>::from(response_result), 
116            RequestResult::RequestError(error)
117        );
118        
119        // Test Ok
120        let params = new_sample_params(10, 20);
121        let response_result = ResponseResult::Result(serde_json::to_value(&params));
122        assert_eq!(
123            RequestResult::<Point, ()>::from(response_result), 
124            RequestResult::MethodResult(Ok(params.clone()))
125        );
126        
127        // Test invalid MethodResult response 
128        let response_result = ResponseResult::Result(serde_json::to_value(&new_sample_params(10, 20)));
129        assert_eq!(
130            RequestResult::<String, ()>::from(response_result), 
131            RequestResult::RequestError(error_JSON_RPC_InvalidResponse(
132                r#"invalid type: map at line 0 column 0"#))
133        );
134    }
135