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

Reply via email to