|
14 | 14 | #[forbid(non_camel_case_types)];
|
15 | 15 | #[allow(missing_doc)];
|
16 | 16 |
|
17 |
| -/*! |
18 |
| -JSON parsing and serialization |
19 |
| -
|
20 |
| -# What is JSON? |
21 |
| -
|
22 |
| -JSON (JavaScript Object Notation) is a way to write data in Javascript. |
23 |
| -Like XML it allows one to encode structured data in a text format that can be read by humans easily. |
24 |
| -Its native compatibility with JavaScript and its simple syntax make it used widely. |
25 |
| -
|
26 |
| -Json data are encoded in a form of "key":"value". |
27 |
| -Data types that can be encoded are JavaScript types : |
28 |
| -boolean (`true` or `false`), number (`f64`), string, array, object, null. |
29 |
| -An object is a series of string keys mapping to values, in `"key": value` format. |
30 |
| -Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). |
31 |
| -A simple JSON document encoding a person, his/her age, address and phone numbers could look like: |
32 |
| -
|
33 |
| -``` |
34 |
| -{ |
35 |
| - "FirstName": "John", |
36 |
| - "LastName": "Doe", |
37 |
| - "Age": 43, |
38 |
| - "Address": { |
39 |
| - "Street": "Downing Street 10", |
40 |
| - "City": "London", |
41 |
| - "Country": "Great Britain" |
42 |
| - }, |
43 |
| - "PhoneNumbers": [ |
44 |
| - "+44 1234567", |
45 |
| - "+44 2345678" |
46 |
| - ] |
47 |
| -} |
48 |
| -``` |
49 |
| -
|
50 |
| -# Rust Type-based Encoding and Decoding |
51 |
| -
|
52 |
| -Rust provides a mechanism for low boilerplate encoding & decoding |
53 |
| -of values to and from JSON via the serialization API. |
54 |
| -To be able to encode a piece of data, it must implement the `extra::serialize::Encodable` trait. |
55 |
| -To be able to decode a piece of data, it must implement the `extra::serialize::Decodable` trait. |
56 |
| -The Rust compiler provides an annotation to automatically generate |
57 |
| -the code for these traits: `#[deriving(Decodable, Encodable)]` |
58 |
| -
|
59 |
| -To encode using Encodable : |
60 |
| -
|
61 |
| -```rust |
62 |
| -use extra::json; |
63 |
| -use std::io; |
64 |
| -use extra::serialize::Encodable; |
65 |
| -
|
66 |
| - #[deriving(Encodable)] |
67 |
| - pub struct TestStruct { |
68 |
| - data_str: ~str, |
69 |
| - } |
70 |
| -
|
71 |
| -fn main() { |
72 |
| - let to_encode_object = TestStruct{data_str:~"example of string to encode"}; |
73 |
| - let mut m = io::MemWriter::new(); |
74 |
| - { |
75 |
| - let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer); |
76 |
| - to_encode_object.encode(&mut encoder); |
77 |
| - } |
78 |
| -} |
79 |
| -``` |
80 |
| -
|
81 |
| -Two wrapper functions are provided to encode a Encodable object |
82 |
| -into a string (~str) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m)`. |
83 |
| -
|
84 |
| -```rust |
85 |
| -use extra::json; |
86 |
| -let to_encode_object = ~"example of string to encode"; |
87 |
| -let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object); |
88 |
| -``` |
89 |
| -
|
90 |
| -JSON API provide an enum `json::Json` and a trait `ToJson` to encode object. |
91 |
| -The trait `ToJson` encode object into a container `json::Json` and the API provide writer |
92 |
| -to encode them into a stream or a string ... |
93 |
| -
|
94 |
| -When using `ToJson` the `Encodable` trait implementation is not mandatory. |
95 |
| -
|
96 |
| -A basic `ToJson` example using a TreeMap of attribute name / attribute value: |
97 |
| -
|
98 |
| -
|
99 |
| -```rust |
100 |
| -use extra::json; |
101 |
| -use extra::json::ToJson; |
102 |
| -use extra::treemap::TreeMap; |
103 |
| -
|
104 |
| -pub struct MyStruct { |
105 |
| - attr1: u8, |
106 |
| - attr2: ~str, |
107 |
| -} |
108 |
| -
|
109 |
| -impl ToJson for MyStruct { |
110 |
| - fn to_json( &self ) -> json::Json { |
111 |
| - let mut d = ~TreeMap::new(); |
112 |
| - d.insert(~"attr1", self.attr1.to_json()); |
113 |
| - d.insert(~"attr2", self.attr2.to_json()); |
114 |
| - json::Object(d) |
115 |
| - } |
116 |
| -} |
117 |
| -
|
118 |
| -fn main() { |
119 |
| - let test2: MyStruct = MyStruct {attr1: 1, attr2:~"test"}; |
120 |
| - let tjson: json::Json = test2.to_json(); |
121 |
| - let json_str: ~str = tjson.to_str(); |
122 |
| -} |
123 |
| -``` |
124 |
| -
|
125 |
| -To decode a json string using `Decodable` trait : |
126 |
| -
|
127 |
| -```rust |
128 |
| -use extra::serialize::Decodable; |
129 |
| -
|
130 |
| -#[deriving(Decodable)] |
131 |
| -pub struct MyStruct { |
132 |
| - attr1: u8, |
133 |
| - attr2: ~str, |
134 |
| -} |
135 |
| -
|
136 |
| -fn main() { |
137 |
| - let json_str_to_decode: ~str = |
138 |
| - ~"{\"attr1\":1,\"attr2\":\"toto\"}"; |
139 |
| - let json_object = extra::json::from_str(json_str_to_decode); |
140 |
| - let mut decoder = extra::json::Decoder::new(json_object.unwrap()); |
141 |
| - let decoded_object: MyStruct = Decodable::decode(&mut decoder); // create the final object |
142 |
| -} |
143 |
| -``` |
144 |
| -
|
145 |
| -# Examples of use |
146 |
| -
|
147 |
| -## Using Autoserialization |
148 |
| -
|
149 |
| -Create a struct called TestStruct1 and serialize and deserialize it to and from JSON |
150 |
| -using the serialization API, using the derived serialization code. |
151 |
| -
|
152 |
| -```rust |
153 |
| -use extra::json; |
154 |
| -use extra::serialize::{Encodable, Decodable}; |
155 |
| -
|
156 |
| - #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl. |
157 |
| - pub struct TestStruct1 { |
158 |
| - data_int: u8, |
159 |
| - data_str: ~str, |
160 |
| - data_vector: ~[u8], |
161 |
| - } |
162 |
| -
|
163 |
| -// To serialize use the `json::str_encode` to encode an object in a string. |
164 |
| -// It calls the generated `Encodable` impl. |
165 |
| -fn main() { |
166 |
| - let to_encode_object = TestStruct1 |
167 |
| - {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]}; |
168 |
| - let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object); |
169 |
| -
|
170 |
| - // To unserialize use the `extra::json::from_str` and `extra::json::Decoder` |
171 |
| -
|
172 |
| - let json_object = extra::json::from_str(encoded_str); |
173 |
| - let mut decoder = json::Decoder::new(json_object.unwrap()); |
174 |
| - let decoded1: TestStruct1 = Decodable::decode(&mut decoder); // create the final object |
175 |
| -} |
176 |
| -``` |
177 |
| -
|
178 |
| -## Using `ToJson` |
179 |
| -
|
180 |
| -This example use the ToJson impl to unserialize the json string. |
181 |
| -Example of `ToJson` trait implementation for TestStruct1. |
182 |
| -
|
183 |
| -```rust |
184 |
| -use extra::json; |
185 |
| -use extra::json::ToJson; |
186 |
| -use extra::serialize::{Encodable, Decodable}; |
187 |
| -use extra::treemap::TreeMap; |
188 |
| -
|
189 |
| -#[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl. |
190 |
| -pub struct TestStruct1 { |
191 |
| - data_int: u8, |
192 |
| - data_str: ~str, |
193 |
| - data_vector: ~[u8], |
194 |
| -} |
195 |
| -
|
196 |
| -impl ToJson for TestStruct1 { |
197 |
| - fn to_json( &self ) -> json::Json { |
198 |
| - let mut d = ~TreeMap::new(); |
199 |
| - d.insert(~"data_int", self.data_int.to_json()); |
200 |
| - d.insert(~"data_str", self.data_str.to_json()); |
201 |
| - d.insert(~"data_vector", self.data_vector.to_json()); |
202 |
| - json::Object(d) |
203 |
| - } |
204 |
| -} |
205 |
| -
|
206 |
| -fn main() { |
207 |
| - // Seralization using our impl of to_json |
208 |
| -
|
209 |
| - let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]}; |
210 |
| - let tjson: json::Json = test2.to_json(); |
211 |
| - let json_str: ~str = tjson.to_str(); |
212 |
| -
|
213 |
| - // Unserialize like before. |
214 |
| -
|
215 |
| - let mut decoder = json::Decoder::new(json::from_str(json_str).unwrap()); |
216 |
| - // create the final object |
217 |
| - let decoded2: TestStruct1 = Decodable::decode(&mut decoder); |
218 |
| -} |
219 |
| -``` |
220 |
| -
|
221 |
| -*/ |
| 17 | +//! json parsing and serialization |
222 | 18 |
|
223 | 19 | use std::char;
|
224 | 20 | use std::cast::transmute;
|
@@ -297,23 +93,6 @@ impl<'a> Encoder<'a> {
|
297 | 93 | pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
|
298 | 94 | Encoder { wr: wr }
|
299 | 95 | }
|
300 |
| - |
301 |
| - /// Encode the specified struct into a json [u8] |
302 |
| - pub fn buffer_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~[u8] { |
303 |
| - //Serialize the object in a string using a writer |
304 |
| - let mut m = MemWriter::new(); |
305 |
| - { |
306 |
| - let mut encoder = Encoder::new(&mut m as &mut io::Writer); |
307 |
| - to_encode_object.encode(&mut encoder); |
308 |
| - } |
309 |
| - m.unwrap() |
310 |
| - } |
311 |
| - |
312 |
| - /// Encode the specified struct into a json str |
313 |
| - pub fn str_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~str { |
314 |
| - let buff:~[u8] = Encoder::buffer_encode(to_encode_object); |
315 |
| - str::from_utf8_owned(buff) |
316 |
| - } |
317 | 96 | }
|
318 | 97 |
|
319 | 98 | impl<'a> serialize::Encoder for Encoder<'a> {
|
@@ -909,7 +688,7 @@ impl<T : Iterator<char>> Parser<T> {
|
909 | 688 | }
|
910 | 689 | }
|
911 | 690 |
|
912 |
| - let exp: f64 = num::pow(10u as f64, exp); |
| 691 | + let exp: f64 = num::pow_with_uint(10u, exp); |
913 | 692 | if neg_exp {
|
914 | 693 | res /= exp;
|
915 | 694 | } else {
|
|
0 commit comments