Module serialize::json[src]

JSON parsing and serialization

What is JSON?

JSON (JavaScript Object Notation) is a way to write data in Javascript. Like XML it allows one to encode structured data in a text format that can be read by humans easily. Its native compatibility with JavaScript and its simple syntax make it used widely.

Json data are encoded in a form of "key":"value". Data types that can be encoded are JavaScript types : boolean (true or false), number (f64), string, array, object, null. An object is a series of string keys mapping to values, in "key": value format. Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). A simple JSON document encoding a person, his/her age, address and phone numbers could look like:

fn main() { { "FirstName": "John", "LastName": "Doe", "Age": 43, "Address": { "Street": "Downing Street 10", "City": "London", "Country": "Great Britain" }, "PhoneNumbers": [ "+44 1234567", "+44 2345678" ] } }
{
    "FirstName": "John",
    "LastName": "Doe",
    "Age": 43,
    "Address": {
        "Street": "Downing Street 10",
        "City": "London",
        "Country": "Great Britain"
    },
    "PhoneNumbers": [
        "+44 1234567",
        "+44 2345678"
    ]
}

Rust Type-based Encoding and Decoding

Rust provides a mechanism for low boilerplate encoding & decoding of values to and from JSON via the serialization API. To be able to encode a piece of data, it must implement the serialize::Encodable trait. To be able to decode a piece of data, it must implement the serialize::Decodable trait. The Rust compiler provides an annotation to automatically generate the code for these traits: #[deriving(Decodable, Encodable)]

To encode using Encodable :

extern crate serialize; use std::io; use serialize::{json, Encodable}; #[deriving(Encodable)] pub struct TestStruct { data_str: String, } fn main() { let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()}; let mut m = io::MemWriter::new(); { let mut encoder = json::Encoder::new(&mut m as &mut Writer); match to_encode_object.encode(&mut encoder) { Ok(()) => (), Err(e) => fail!("json encoding error: {}", e) }; } }
use std::io;
use serialize::{json, Encodable};

 #[deriving(Encodable)]
 pub struct TestStruct   {
    data_str: String,
 }

fn main() {
    let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()};
    let mut m = io::MemWriter::new();
    {
        let mut encoder = json::Encoder::new(&mut m as &mut Writer);
        match to_encode_object.encode(&mut encoder) {
            Ok(()) => (),
            Err(e) => fail!("json encoding error: {}", e)
        };
    }
}

Two wrapper functions are provided to encode a Encodable object into a string (String) or buffer (vec![u8]): str_encode(&m) and buffer_encode(&m).

extern crate serialize; fn main() { use serialize::json; let to_encode_object = "example of string to encode".to_string(); let encoded_str: String = json::Encoder::str_encode(&to_encode_object); }
use serialize::json;
let to_encode_object = "example of string to encode".to_string();
let encoded_str: String = json::Encoder::str_encode(&to_encode_object);

JSON API provide an enum json::Json and a trait ToJson to encode object. The trait ToJson encode object into a container json::Json and the API provide writer to encode them into a stream or a string ...

When using ToJson the Encodable trait implementation is not mandatory.

A basic ToJson example using a TreeMap of attribute name / attribute value:

extern crate serialize; use std::collections::TreeMap; use serialize::json; use serialize::json::ToJson; pub struct MyStruct { attr1: u8, attr2: String, } impl ToJson for MyStruct { fn to_json( &self ) -> json::Json { let mut d = box TreeMap::new(); d.insert("attr1".to_string(), self.attr1.to_json()); d.insert("attr2".to_string(), self.attr2.to_json()); json::Object(d) } } fn main() { let test2: MyStruct = MyStruct {attr1: 1, attr2:"test".to_string()}; let tjson: json::Json = test2.to_json(); let json_str: String = tjson.to_str().into_string(); }
use std::collections::TreeMap;
use serialize::json;
use serialize::json::ToJson;

pub struct MyStruct  {
    attr1: u8,
    attr2: String,
}

impl ToJson for MyStruct {
    fn to_json( &self ) -> json::Json {
        let mut d = box TreeMap::new();
        d.insert("attr1".to_string(), self.attr1.to_json());
        d.insert("attr2".to_string(), self.attr2.to_json());
        json::Object(d)
    }
}

fn main() {
    let test2: MyStruct = MyStruct {attr1: 1, attr2:"test".to_string()};
    let tjson: json::Json = test2.to_json();
    let json_str: String = tjson.to_str().into_string();
}

To decode a JSON string using Decodable trait :

extern crate serialize; use serialize::{json, Decodable}; #[deriving(Decodable)] pub struct MyStruct { attr1: u8, attr2: String, } fn main() { let json_str_to_decode: String = "{\"attr1\":1,\"attr2\":\"toto\"}".to_string(); let json_object = json::from_str(json_str_to_decode.as_slice()); let mut decoder = json::Decoder::new(json_object.unwrap()); let decoded_object: MyStruct = match Decodable::decode(&mut decoder) { Ok(v) => v, Err(e) => fail!("Decoding error: {}", e) }; // create the final object }
extern crate serialize;
use serialize::{json, Decodable};

#[deriving(Decodable)]
pub struct MyStruct  {
     attr1: u8,
     attr2: String,
}

fn main() {
    let json_str_to_decode: String =
            "{\"attr1\":1,\"attr2\":\"toto\"}".to_string();
    let json_object = json::from_str(json_str_to_decode.as_slice());
    let mut decoder = json::Decoder::new(json_object.unwrap());
    let decoded_object: MyStruct = match Decodable::decode(&mut decoder) {
        Ok(v) => v,
        Err(e) => fail!("Decoding error: {}", e)
    }; // create the final object
}

Examples of use

Using Autoserialization

Create a struct called TestStruct1 and serialize and deserialize it to and from JSON using the serialization API, using the derived serialization code.

extern crate serialize; use serialize::{json, Encodable, Decodable}; #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl. pub struct TestStruct1 { data_int: u8, data_str: String, data_vector: Vec<u8>, } // To serialize use the `json::str_encode` to encode an object in a string. // It calls the generated `Encodable` impl. fn main() { let to_encode_object = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]}; let encoded_str: String = json::Encoder::str_encode(&to_encode_object); // To deserialize use the `json::from_str` and `json::Decoder` let json_object = json::from_str(encoded_str.as_slice()); let mut decoder = json::Decoder::new(json_object.unwrap()); let decoded1: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); // create the final object }
extern crate serialize;
use serialize::{json, Encodable, Decodable};

 #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl.
 pub struct TestStruct1  {
    data_int: u8,
    data_str: String,
    data_vector: Vec<u8>,
 }

// To serialize use the `json::str_encode` to encode an object in a string.
// It calls the generated `Encodable` impl.
fn main() {
    let to_encode_object = TestStruct1
         {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
    let encoded_str: String = json::Encoder::str_encode(&to_encode_object);

    // To deserialize use the `json::from_str` and `json::Decoder`

    let json_object = json::from_str(encoded_str.as_slice());
    let mut decoder = json::Decoder::new(json_object.unwrap());
    let decoded1: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); // create the final object
}

Using ToJson

This example uses the ToJson impl to deserialize the JSON string. Example of ToJson trait implementation for TestStruct1.

extern crate serialize; use std::collections::TreeMap; use serialize::json::ToJson; use serialize::{json, Encodable, Decodable}; #[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl. pub struct TestStruct1 { data_int: u8, data_str: String, data_vector: Vec<u8>, } impl ToJson for TestStruct1 { fn to_json( &self ) -> json::Json { let mut d = box TreeMap::new(); d.insert("data_int".to_string(), self.data_int.to_json()); d.insert("data_str".to_string(), self.data_str.to_json()); d.insert("data_vector".to_string(), self.data_vector.to_json()); json::Object(d) } } fn main() { // Serialization using our impl of to_json let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]}; let tjson: json::Json = test2.to_json(); let json_str: String = tjson.to_str().into_string(); // Deserialize like before. let mut decoder = json::Decoder::new(json::from_str(json_str.as_slice()).unwrap()); // create the final object let decoded2: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); }
use std::collections::TreeMap;
use serialize::json::ToJson;
use serialize::{json, Encodable, Decodable};

#[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl.
pub struct TestStruct1  {
    data_int: u8,
    data_str: String,
    data_vector: Vec<u8>,
}

impl ToJson for TestStruct1 {
    fn to_json( &self ) -> json::Json {
        let mut d = box TreeMap::new();
        d.insert("data_int".to_string(), self.data_int.to_json());
        d.insert("data_str".to_string(), self.data_str.to_json());
        d.insert("data_vector".to_string(), self.data_vector.to_json());
        json::Object(d)
    }
}

fn main() {
    // Serialization using our impl of to_json

    let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:"toto".to_string(),
                                          data_vector:vec![2,3,4,5]};
    let tjson: json::Json = test2.to_json();
    let json_str: String = tjson.to_str().into_string();

    // Deserialize like before.

    let mut decoder =
        json::Decoder::new(json::from_str(json_str.as_slice()).unwrap());
    // create the final object
    let decoded2: TestStruct1 = Decodable::decode(&mut decoder).unwrap();
}

Structs

Builder

A Builder consumes a json::Parser to create a generic Json structure.

Decoder

A structure to decode JSON to values in rust.

Encoder

A structure for implementing serialization to JSON.

Parser

A streaming JSON parser implemented as an iterator of JsonEvent, consuming an iterator of char.

PrettyEncoder

Another encoder for JSON, but prints out human-readable JSON instead of compact data

Stack

A Stack represents the current position of the parser in the logical structure of the JSON stream. For example foo.bar[3].x

Enums

DecoderError
ErrorCode

The errors that can arise while parsing a JSON stream.

Json

Represents a json value

JsonEvent

The output of the streaming parser.

ParserError
StackElement

StackElements compose a Stack. For example, Key("foo"), Key("bar"), Index(3) and Key("x") are the StackElements compositing the stack that represents foo.bar[3].x

Traits

ToJson

A trait for converting values to JSON

Functions

error_str

Returns a readable error string for a given error code.

from_reader

Decodes a json value from an &mut io::Reader

from_str

Decodes a json value from a string

Type Definitions

BuilderError
DecodeResult
EncodeResult
List
Object