jsonrpc/
jsonrpc_common.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
8use std::fmt;
9
10use serde;
11use serde::de::Visitor;
12use serde::Error;
13
14use serde_json::Value;
15use serde_json;
16use json_util::*;
17
18
19
20pub type JsonRpcParseResult<T> = Result<T, RequestError>;
21
22pub fn parse_jsonrpc_id(id: Value) -> JsonRpcParseResult<Option<Id>> {
23    serde_json::from_value(id)
24        .map_err(|err| error_JSON_RPC_InvalidRequest(format!("Invalid id: {}", err)))
25}
26
27
28/* ----------------- Id ----------------- */
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31/// A JSON RPC Id
32/// Note: only supports u64 numbers
33pub enum Id { Number(u64), String(String), Null, }
34
35impl serde::Serialize for Id {
36    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
37        where S: serde::Serializer,
38    {
39        match *self {
40            Id::Null => serializer.serialize_none(),
41            Id::Number(number) => serializer.serialize_u64(number), 
42            Id::String(ref string) => serializer.serialize_str(string),
43        }
44    }
45}
46
47impl serde::Deserialize for Id {
48    fn deserialize<DE>(deserializer: &mut DE) -> Result<Self, DE::Error>
49        where DE: serde::Deserializer 
50    {
51        deserializer.deserialize(IdDeserializeVisitor)
52    }
53}
54
55struct IdDeserializeVisitor;
56
57impl Visitor for IdDeserializeVisitor {
58    type Value = Id;
59    
60    fn visit_unit<E>(&mut self) -> Result<Self::Value, E> where E: Error,
61    {
62        Ok(Id::Null)
63    }
64    
65    fn visit_u64<E>(&mut self, value: u64) -> Result<Self::Value, E> where E: Error,
66    {
67        Ok(Id::Number(value))
68    }
69    
70    fn visit_str<E>(&mut self, value: &str) -> Result<Self::Value, E> where E: Error,
71    {
72        Ok(Id::String(value.to_string()))
73    }
74}
75
76impl fmt::Display for Id {
77    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
78        write!(fmt, "{}", serde_json::to_string(self).unwrap())
79    }
80}
81
82#[test]
83fn test_Id() {
84    use json_util::test_util::*;
85    
86    test_serde(&Id::Null);
87    test_serde(&Id::Number(123));
88    test_serde(&Id::String("123".into()));
89    test_serde(&Id::String("".into()));
90    test_serde(&Id::String("foo".into()));
91    
92    // FIXME better handling of non-u64 numbers?
93//    assert_eq!(from_json::<Id>("-123"), Id::Number(123)); 
94}
95
96
97/* -----------------  Error  ----------------- */
98
99#[derive(Debug, PartialEq, Clone)]
100pub struct RequestError {
101    pub code : i64,
102    pub message : String,
103    pub data : Option<Value>,
104}
105
106impl RequestError {
107    pub fn new(code: i64, message: String) -> RequestError {
108        RequestError { code : code, message : message, data : None }
109    }
110}
111
112pub fn error_JSON_RPC_ParseError<T: fmt::Display>(error: T) -> RequestError { 
113    RequestError::new(-32700, format!("Invalid JSON was received by the server: {}", error).to_string())
114}
115pub fn error_JSON_RPC_InvalidRequest<T: fmt::Display>(error: T) -> RequestError { 
116    RequestError::new(-32600, format!("The JSON sent is not a valid Request object: {}", error).to_string())
117}
118pub fn error_JSON_RPC_MethodNotFound() -> RequestError { 
119    RequestError::new(-32601, "The method does not exist / is not available.".to_string())
120}
121pub fn error_JSON_RPC_InvalidParams<T: fmt::Display>(error: T) -> RequestError { 
122    RequestError::new(-32602, format!("Invalid method parameter(s): {}", error).to_string())
123}
124pub fn error_JSON_RPC_InternalError() -> RequestError { 
125    RequestError::new(-32603, "Internal JSON-RPC error.".to_string())
126}
127
128pub fn error_JSON_RPC_InvalidResponse<T: fmt::Display>(error: T) -> RequestError { 
129    RequestError::new(-32000, format!("Invalid method response: {}", error).to_string())
130}
131
132impl serde::Serialize for RequestError {
133    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
134        where S: serde::Serializer
135    {
136        let elem_count = 3;
137        let mut state = try!(serializer.serialize_struct("RequestError", elem_count)); 
138        {
139            try!(serializer.serialize_struct_elt(&mut state, "code", self.code));
140            try!(serializer.serialize_struct_elt(&mut state, "message", &self.message));
141            if let Some(ref data) = self.data {
142                try!(serializer.serialize_struct_elt(&mut state, "data", data));
143            }
144        }
145        serializer.serialize_struct_end(state)
146    }
147}
148
149impl serde::Deserialize for RequestError {
150    fn deserialize<DE>(deserializer: &mut DE) -> Result<Self, DE::Error>
151        where DE: serde::Deserializer 
152    {
153        let mut helper = SerdeJsonDeserializerHelper(deserializer);
154        let value : Value = try!(Value::deserialize(helper.0));
155        let mut json_obj = try!(helper.as_Object(value));
156        
157        let code = try!(helper.obtain_i64(&mut json_obj, "code"));
158        let message = try!(helper.obtain_String(&mut json_obj, "message"));
159        
160        let data = json_obj.remove("data"); 
161        
162        Ok(RequestError{ code : code, message : message, data : data }) 
163    }
164}
165
166#[test]
167fn test_RequestError() {
168    use json_util::test_util::*;
169    
170    test_serde(&RequestError::new(12, "asd".into()));
171    test_serde(&RequestError{ code : -123, message : "abc".into(), data : None });
172    
173    test_serde(&RequestError{ code : 1, message : "xxx".into(), data : Some(Value::Null) });
174    test_serde(&RequestError{ code : 1, message : "xxx".into(), data : Some(Value::String("asdf".into())) });
175    
176    test_error_de::<RequestError>("{}", "Property `code` is missing");
177}