]>
Commit | Line | Data |
---|---|---|
9eb78407 | 1 | use anyhow::{bail, format_err, Error}; |
9ff747ef WB |
2 | use serde_json::Value; |
3 | ||
4 | // Generate canonical json | |
5 | pub fn to_canonical_json(value: &Value) -> Result<Vec<u8>, Error> { | |
6 | let mut data = Vec::new(); | |
7 | write_canonical_json(value, &mut data)?; | |
8 | Ok(data) | |
9 | } | |
10 | ||
11 | pub fn write_canonical_json(value: &Value, output: &mut Vec<u8>) -> Result<(), Error> { | |
12 | match value { | |
13 | Value::Null => bail!("got unexpected null value"), | |
14 | Value::String(_) | Value::Number(_) | Value::Bool(_) => { | |
15 | serde_json::to_writer(output, &value)?; | |
16 | } | |
17 | Value::Array(list) => { | |
18 | output.push(b'['); | |
19 | let mut iter = list.iter(); | |
20 | if let Some(item) = iter.next() { | |
21 | write_canonical_json(item, output)?; | |
22 | for item in iter { | |
23 | output.push(b','); | |
24 | write_canonical_json(item, output)?; | |
25 | } | |
26 | } | |
27 | output.push(b']'); | |
28 | } | |
29 | Value::Object(map) => { | |
30 | output.push(b'{'); | |
31 | let mut keys: Vec<&str> = map.keys().map(String::as_str).collect(); | |
ea368a06 | 32 | keys.sort_unstable(); |
9ff747ef WB |
33 | let mut iter = keys.into_iter(); |
34 | if let Some(key) = iter.next() { | |
35 | serde_json::to_writer(&mut *output, &key)?; | |
36 | output.push(b':'); | |
37 | write_canonical_json(&map[key], output)?; | |
38 | for key in iter { | |
39 | output.push(b','); | |
40 | serde_json::to_writer(&mut *output, &key)?; | |
41 | output.push(b':'); | |
42 | write_canonical_json(&map[key], output)?; | |
43 | } | |
44 | } | |
45 | output.push(b'}'); | |
46 | } | |
47 | } | |
48 | Ok(()) | |
49 | } | |
9eb78407 WB |
50 | |
51 | pub fn json_object_to_query(data: Value) -> Result<String, Error> { | |
52 | let mut query = url::form_urlencoded::Serializer::new(String::new()); | |
53 | ||
54 | let object = data.as_object().ok_or_else(|| { | |
55 | format_err!("json_object_to_query: got wrong data type (expected object).") | |
56 | })?; | |
57 | ||
58 | for (key, value) in object { | |
59 | match value { | |
60 | Value::Bool(b) => { | |
61 | query.append_pair(key, &b.to_string()); | |
62 | } | |
63 | Value::Number(n) => { | |
64 | query.append_pair(key, &n.to_string()); | |
65 | } | |
66 | Value::String(s) => { | |
67 | query.append_pair(key, &s); | |
68 | } | |
69 | Value::Array(arr) => { | |
70 | for element in arr { | |
71 | match element { | |
72 | Value::Bool(b) => { | |
73 | query.append_pair(key, &b.to_string()); | |
74 | } | |
75 | Value::Number(n) => { | |
76 | query.append_pair(key, &n.to_string()); | |
77 | } | |
78 | Value::String(s) => { | |
79 | query.append_pair(key, &s); | |
80 | } | |
81 | _ => bail!( | |
82 | "json_object_to_query: unable to handle complex array data types." | |
83 | ), | |
84 | } | |
85 | } | |
86 | } | |
87 | _ => bail!("json_object_to_query: unable to handle complex data types."), | |
88 | } | |
89 | } | |
90 | ||
91 | Ok(query.finish()) | |
92 | } | |
3c8c2827 WB |
93 | |
94 | pub fn required_string_param<'a>(param: &'a Value, name: &str) -> Result<&'a str, Error> { | |
95 | match param[name].as_str() { | |
96 | Some(s) => Ok(s), | |
97 | None => bail!("missing parameter '{}'", name), | |
98 | } | |
99 | } | |
100 | ||
101 | pub fn required_string_property<'a>(param: &'a Value, name: &str) -> Result<&'a str, Error> { | |
102 | match param[name].as_str() { | |
103 | Some(s) => Ok(s), | |
104 | None => bail!("missing property '{}'", name), | |
105 | } | |
106 | } | |
107 | ||
108 | pub fn required_integer_param(param: &Value, name: &str) -> Result<i64, Error> { | |
109 | match param[name].as_i64() { | |
110 | Some(s) => Ok(s), | |
111 | None => bail!("missing parameter '{}'", name), | |
112 | } | |
113 | } | |
114 | ||
115 | pub fn required_integer_property(param: &Value, name: &str) -> Result<i64, Error> { | |
116 | match param[name].as_i64() { | |
117 | Some(s) => Ok(s), | |
118 | None => bail!("missing property '{}'", name), | |
119 | } | |
120 | } | |
121 | ||
122 | pub fn required_array_param<'a>(param: &'a Value, name: &str) -> Result<&'a [Value], Error> { | |
123 | match param[name].as_array() { | |
124 | Some(s) => Ok(&s), | |
125 | None => bail!("missing parameter '{}'", name), | |
126 | } | |
127 | } | |
128 | ||
129 | pub fn required_array_property<'a>(param: &'a Value, name: &str) -> Result<&'a [Value], Error> { | |
130 | match param[name].as_array() { | |
131 | Some(s) => Ok(&s), | |
132 | None => bail!("missing property '{}'", name), | |
133 | } | |
134 | } |