jsonrpc/
json_util.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::collections::BTreeMap;
9use std::fmt;
10
11use serde;
12
13use serde_json::Map;
14use serde_json::Value;
15use serde_json::builder::ObjectBuilder;
16
17pub type JsonObject = Map<String, Value>;
18
19/* ----------------- deserialize helpers ----------------- */
20
21pub fn new_object() -> JsonObject {
22    BTreeMap::new()
23}
24
25pub fn unwrap_object_builder(ob: ObjectBuilder) -> JsonObject {
26    unwrap_object(ob.build())
27}
28
29pub fn unwrap_object(value: Value) -> JsonObject {
30    match value {
31        Value::Object(o) => o ,
32        _ => { panic!() },
33    }
34}
35
36/* -----------------  ----------------- */
37
38pub trait JsonDeserializerHelper<ERR> {
39    
40    fn new_error(&self, error_message: &str) -> ERR;
41    
42    fn obtain_Value(&mut self, mut json_map : &mut JsonObject, key: & str) 
43        -> Result<Value, ERR>
44    {
45        let value = json_map.remove(key);
46        match value {
47            Some(value) => { Ok(value) },
48            None => { return Err(self.new_error(&format!("Property `{}` is missing.", key))) }
49        }
50    }
51    
52    fn obtain_Value_or(&mut self, mut json_map : &mut JsonObject, key: & str, default: & Fn() -> Value) 
53        -> Value 
54    {
55        if let Some(value) = json_map.remove(key) {
56            if let Value::Null = value {
57                default()
58            } else {
59                value
60            }
61        } else {
62            default()
63        }
64    }
65    
66    fn as_String(&mut self, value: Value) -> Result<String, ERR> {
67        match value {
68            Value::String(string) => Ok(string),
69            _ => Err(self.new_error(&format!("Value `{}` is not a String.", value))),
70        }
71    }
72    
73    fn as_Object(&mut self, value: Value) -> Result<JsonObject, ERR> {
74        match value {
75            Value::Object(map) => Ok(map),
76            _ => Err(self.new_error(&format!("Value `{}` is not an Object.", value))),
77        }
78    }
79    
80    fn as_u32(&mut self, value: Value) -> Result<u32, ERR> {
81        match value {
82            Value::I64(num) => Ok(num as u32), // FIXME: check for truncation
83            Value::U64(num) => Ok(num as u32), // FIXME: check for truncation
84            _ => Err(self.new_error(&format!("Value `{}` is not an Integer.", value))),
85        }
86    }
87    
88    fn as_i64(&mut self, value: Value) -> Result<i64, ERR> {
89        match value {
90            Value::I64(num) => Ok(num),
91            Value::U64(num) => Ok(num as i64), // FIXME: check for truncation
92            _ => Err(self.new_error(&format!("Value `{}` is not an Integer.", value))),
93        }
94    }
95    
96    
97    fn obtain_String(&mut self, json_map : &mut JsonObject, key: &str) 
98        -> Result<String, ERR> 
99    {
100        let value = try!(self.obtain_Value(json_map, key));
101        self.as_String(value)
102    }
103    
104    fn obtain_Object(&mut self, json_map : &mut JsonObject, key: &str) 
105        -> Result<JsonObject, ERR> 
106    {
107        let value = try!(self.obtain_Value(json_map, key));
108        self.as_Object(value)
109    }
110    
111    fn obtain_Object_or(&mut self, json_map : &mut JsonObject, key: &str, default: & Fn() -> JsonObject) 
112        -> Result<JsonObject, ERR> 
113    {
114        let value = self.obtain_Value_or(json_map, key, &|| { Value::Object(default()) });
115        self.as_Object(value)
116    }
117    
118    fn obtain_u32(&mut self, json_map: &mut JsonObject, key: &str) 
119        -> Result<u32, ERR> 
120    {
121        let value = try!(self.obtain_Value(json_map, key));
122        self.as_u32(value)
123    }
124    
125    fn obtain_i64(&mut self, json_map: &mut JsonObject, key: &str) 
126        -> Result<i64, ERR> 
127    {
128        let value = try!(self.obtain_Value(json_map, key));
129        self.as_i64(value)
130    }
131
132}
133
134pub struct SerdeJsonDeserializerHelper<DE>(pub DE);
135
136impl<'a, DE : serde::Deserializer> 
137    JsonDeserializerHelper<DE::Error> for SerdeJsonDeserializerHelper<&'a mut DE> 
138{
139    fn new_error(&self, error_message: &str) -> DE::Error {
140        new_de_error(error_message.into())
141    }
142}
143
144pub fn to_de_error<DISPLAY, DE_ERROR>(display: DISPLAY) 
145    -> DE_ERROR   
146where 
147    DISPLAY: fmt::Display,
148    DE_ERROR: serde::Error, 
149{
150    DE_ERROR::custom(format!("{}", display))
151}
152
153pub fn new_de_error<DE_ERROR>(message: String) 
154    -> DE_ERROR
155    where DE_ERROR: serde::Error 
156{
157    DE_ERROR::custom(message)
158}
159
160/* -----------------  ----------------- */
161
162#[cfg(test)]
163pub mod test_util {
164    
165    use util::tests::*;
166    use serde::Serialize;
167    use serde::Deserialize;
168    use serde_json;
169    use serde_json::Value;
170    use std::fmt::Debug;
171    
172    pub fn to_json<T: Serialize>(value: &T) -> String {
173        serde_json::to_string(value).unwrap()
174    }
175    
176    pub fn from_json<T: Deserialize>(json: &str) -> T {
177        serde_json::from_str(json).unwrap()
178    }
179
180    pub fn test_serde<T>(obj: &T) 
181        -> (T, String)
182        where T : Serialize + Deserialize + PartialEq + Debug
183    {
184        let json = to_json(obj);
185        let reserialized : T = from_json(&json);
186        check_equal(&reserialized, obj);
187        (reserialized, json)
188    }
189    
190    pub fn test_error_de<T>(json: &str, expected_err_contains: &str) 
191        where T : Deserialize + PartialEq + Debug
192    {
193        let res = serde_json::from_str::<T>(json).unwrap_err();
194        check_err_contains(res, expected_err_contains);
195    }
196    
197    pub fn test_serde_expecting<T>(obj: &T, expected_value: &Value) 
198        -> Value
199        where T : Serialize + Deserialize + PartialEq + Debug
200    {
201        let json = test_serde(obj).1;
202        
203        let as_value : Value = serde_json::from_str(&json).unwrap();
204        check_equal(&as_value, expected_value);
205        as_value
206    }
207    
208}