Skip to content

Commit bf0043d

Browse files
committed
auto merge of #10801 : musitdev/rust/jsondoc2, r=cmr
I update the example of json use to the last update of the json.rs code. I delete the old branch. From my last request, I remove the example3 because it doesn't compile. I don't understand why and I don't have the time now to investigate.
2 parents 18061e8 + aeb5416 commit bf0043d

File tree

1 file changed

+222
-1
lines changed

1 file changed

+222
-1
lines changed

src/libextra/json.rs

+222-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,211 @@
1414
#[forbid(non_camel_case_types)];
1515
#[allow(missing_doc)];
1616

17-
//! json parsing and serialization
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+
*/
18222

19223
use std::char;
20224
use std::cast::transmute;
@@ -93,6 +297,23 @@ impl<'a> Encoder<'a> {
93297
pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
94298
Encoder { wr: wr }
95299
}
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+
}
96317
}
97318

98319
impl<'a> serialize::Encoder for Encoder<'a> {

0 commit comments

Comments
 (0)