I finished my test with the rust json API. I made a non trivial example
code that summaries what I understand. I put it at the end of the mail.
Could someone (the developer of the API for example) add it to the
comment of the json API. I don't think I have the right. It can be good
to add it as a test case to validate that it stay up to date.
Put any remarks about the code if I've made some mistake or if there is
better code.
I have a general remark about the json.rs. It's copyrighted by Rust
developer and google.
Philippe
The code :
#[link(name = "test_json", vers = "0.1", author = "Philippe Delrieu")];
#[feature(managed_boxes)];
extern mod extra;
use std::io::mem::MemWriter;
use extra::serialize::Decodable;
use extra::serialize::Encodable;
use extra::serialize::Encoder;
use extra::json::{Json, Decoder, ToJson, Object};
use extra::treemap::TreeMap;
use std::io::Decorator;
//first struct with auto generate Decodable, Encodable
#[deriving(Decodable, Encodable, Eq)] //generate Decodable, Encodable
impl. Eq is added for the test assert.
pub struct TestStruct1 {
dataInt: u8,
dataStr:~str,
dataArray:~[u8],
}
fn Test1() {
//first possibility to use JSON is the serialization API. Use a
struct that implement Decodable, Encodable.
//the object to test
let test : TestStruct1 = TestStruct1 {dataInt: 1, dataStr:~"toto",
dataArray:~[2,3,4,5]}; // encoded
~"{\"dataInt\":1,\"dataStr\":\"toto\",\"dataArray\":[2,3,4,5]}"
//Serialize the object in a string using a writer
let m = @mut MemWriter::new();
let mut encoder = extra::json::Encoder(m as @mut Writer);
test.encode(&mut encoder);
let buf:&~[u8] = m.inner_ref(); //get the serialized values.
let s = std::str::from_utf8(*buf);
println!("test 1 encoded using auto generated Encodable {:?}", s);
assert_eq!(s,
~"{\"dataInt\":1,\"dataStr\":\"toto\",\"dataArray\":[2,3,4,5]}");
//unserialize using the object decoder
//convert the string to a json object.
let jsonobject = extra::json::from_str(s);
let mut decoder = Decoder(jsonobject.unwrap());
let decoded1: TestStruct1 = Decodable::decode(&mut decoder);
//create the final object
println!("test 1 decoded using auto generated Decodable {:?}",
decoded1);
assert_eq!(decoded1, test);
}
//second struct with manually implemented Decodable, Encodable
#[deriving(Eq)] //generate impl of Eq for the test assert.
pub struct TestStruct2 {
dataInt: u8,
dataStr:~str,
dataArray:~[u8],
}
impl<S:Encoder> Encodable<S> for TestStruct2 {
fn encode(&self, s: &mut S) {
do s.emit_struct("TestStruct2", 2) |s| { //2 correspond to
len the number of field in the structure.
s.emit_struct_field("dataInt", 0, |s| self.dataInt.encode(s));
s.emit_struct_field("dataStr", 1, |s| self.dataStr.encode(s));
//encode the dataArray array field with emit_seq
do s.emit_struct_field("dataArray", 3) |s| {
do s.emit_seq(self.dataArray.len()) |s| { //len
number of element in the array.
for i in range(0u, self.dataArray.len()) {
s.emit_seq_elt(i, |s| self.dataArray[i].encode(s));
}
}
}
}
}
}
impl<D:extra::serialize::Decoder> extra::serialize::Decodable<D> for
TestStruct2 {
fn decode(d: &mut D) -> TestStruct2 {
do d.read_struct("TestStruct2", 1) |d| {
TestStruct2
{
dataInt: d.read_struct_field("dataInt", 0, |d|
d.read_u8()),
dataStr: d.read_struct_field("dataStr", 1, |d|
d.read_str()),
dataArray: do d.read_struct_field("dataArray", 2) |d| {
let mut arr:~[u8] = ~[];
do d.read_seq |d, len| {
for i in range(0u, len) {
arr.push(d.read_seq_elt(i, |d| d.read_u8()));
}
}
arr
}
}
}
}
}
//second possibility to decode json is to implement the ToJson trait.
impl ToJson for TestStruct2 {
fn to_json( &self ) -> Json {
let mut d = ~TreeMap::new();
d.insert(~"dataInt", self.dataInt.to_json());
d.insert(~"dataStr", self.dataStr.to_json());
d.insert(~"dataArray", self.dataArray.to_json());
Object(d)
}
}
fn Test2() {
//second possibility : use impl of to_json() to serialize
let test2 : TestStruct2 = TestStruct2 {dataInt: 1, dataStr:~"toto",
dataArray:~[2,3,4,5]};
//{\"dataArray\":[2,3,4,5],\"dataInt\":1,\"dataStr\":\"toto\"}
let tjson : Json = test2.to_json();
let jsonStr:~str = tjson.to_str();
println!("Test 2 encoded using to_json {:?}", jsonStr);
assert_eq!(jsonStr,
~"{\"dataArray\":[2,3,4,5],\"dataInt\":1,\"dataStr\":\"toto\"}");
//unserialize using the our own impl of decoder
//convert the string to a json object and decode.
let mut decoder = Decoder(extra::json::from_str(jsonStr).unwrap());
let decoded2: TestStruct2 = Decodable::decode(&mut decoder);
//create the final object
println!("test 2 decoded using our Decodable{:?}", decoded2);
assert_eq!(decoded2, test2);
}
fn Test3() {
//thrid use our own encoder to encode
let test3 : TestStruct2 = TestStruct2 {dataInt: 1, dataStr:~"toto",
dataArray:~[2,3,4,5]};
//{\"dataArray\":[2,3,4,5],\"dataInt\":1,\"dataStr\":\"toto\"}
let m3 = @mut MemWriter::new();
let mut encoder3 = extra::json::Encoder(m3 as @mut Writer);
test3.encode(&mut encoder3);
let buf3:&~[u8] = m3.inner_ref(); //get the serialized values.
let s3 = std::str::from_utf8(*buf3);
println!("test 3 encoded using our Encodable {:?}", s3);
//decode using error management and our own decoder.
let j:Result<extra::json::Json,extra::json::Error> =
extra::json::from_str(s3);
let json: extra::json::Json = match j {
Ok(l) => l,
Err(e) => fail!(format!("Error: {:?}", e))
};
let mut decoder3 = Decoder(json);
let decoded3: TestStruct2 = Decodable::decode(&mut decoder3);
//create the final object
println!("test 3 decoded using our Decodable {:?}", decoded3);
assert_eq!(decoded3, test3);
}
#[main]
fn main() {
Test1();
Test2();
Test3();
}
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev