Module rustc_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 encoding structured data in a text format that can be easily read by humans. Its simple syntax and native compatibility with JavaScript have made it a widely used format.

Data types that can be encoded are JavaScript types (see the Json enum for more details):

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, their age, address and phone numbers could look like

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

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 rustc_serialize::Encodable trait. To be able to decode a piece of data, it must implement the rustc_serialize::Decodable trait. The Rust compiler provides an annotation to automatically generate the code for these traits: #[derive(RustcDecodable, RustcEncodable)]

The JSON API provides an enum json::Json and a trait ToJson to encode objects. The ToJson trait provides a to_json method to convert an object into a json::Json value. A json::Json value can be encoded as a string or buffer using the functions described above. You can also use the json::Encoder object, which implements the Encoder trait.

When using ToJson, the Encodable trait implementation is not mandatory.

Examples of use

Using Autoserialization

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

extern crate rustc_serialize;
use rustc_serialize::json;

// Automatically generate `RustcDecodable` and `RustcEncodable` trait
// implementations
#[derive(RustcDecodable, RustcEncodable)]
pub struct TestStruct  {
    data_int: u8,
    data_str: String,
    data_vector: Vec<u8>,
}

fn main() {
    let object = TestStruct {
        data_int: 1,
        data_str: "homura".to_string(),
        data_vector: vec![2,3,4,5],
    };

    // Serialize using `json::encode`
    let encoded = json::encode(&object).unwrap();

    // Deserialize using `json::decode`
    let decoded: TestStruct = json::decode(&encoded).unwrap();
}Run

Using the ToJson trait

The examples below use the ToJson trait to generate the JSON string, which is required for custom mappings.

Simple example of ToJson usage

extern crate rustc_serialize;
use rustc_serialize::json::{self, ToJson, Json};

// A custom data structure
struct ComplexNum {
    a: f64,
    b: f64,
}

// JSON value representation
impl ToJson for ComplexNum {
    fn to_json(&self) -> Json {
        Json::String(format!("{}+{}i", self.a, self.b))
    }
}

// Only generate `RustcEncodable` trait implementation
#[derive(RustcEncodable)]
pub struct ComplexNumRecord {
    uid: u8,
    dsc: String,
    val: Json,
}

fn main() {
    let num = ComplexNum { a: 0.0001, b: 12.539 };
    let data: String = json::encode(&ComplexNumRecord{
        uid: 1,
        dsc: "test".to_string(),
        val: num.to_json(),
    }).unwrap();
    println!("data: {}", data);
    // data: {"uid":1,"dsc":"test","val":"0.0001+12.539i"};
}Run

Verbose example of ToJson usage

extern crate rustc_serialize;
use std::collections::BTreeMap;
use rustc_serialize::json::{self, Json, ToJson};

// Only generate `Decodable` trait implementation
#[derive(RustcDecodable)]
pub struct TestStruct {
    data_int: u8,
    data_str: String,
    data_vector: Vec<u8>,
}

// Specify encoding method manually
impl ToJson for TestStruct {
    fn to_json(&self) -> Json {
        let mut d = BTreeMap::new();
        // All standard types implement `to_json()`, so use it
        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() {
    // Serialize using `ToJson`
    let input_data = TestStruct {
        data_int: 1,
        data_str: "madoka".to_string(),
        data_vector: vec![2,3,4,5],
    };
    let json_obj: Json = input_data.to_json();
    let json_str: String = json_obj.to_string();

    // Deserialize like before
    let decoded: TestStruct = json::decode(&json_str).unwrap();
}Run

Parsing a str to Json and reading the result

extern crate rustc_serialize;
use rustc_serialize::json::Json;

fn main() {
    let data = Json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
    println!("data: {}", data);
    // data: {"bar":"baz","foo":13}
    println!("object? {}", data.is_object());
    // object? true

    let obj = data.as_object().unwrap();
    let foo = obj.get("foo").unwrap();

    println!("array? {:?}", foo.as_array());
    // array? None
    println!("u64? {:?}", foo.as_u64());
    // u64? Some(13u64)

    for (key, value) in obj.iter() {
        println!("{}: {}", key, match *value {
            Json::U64(v) => format!("{} (u64)", v),
            Json::String(ref v) => format!("{} (string)", v),
            _ => format!("other")
        });
    }
    // bar: baz (string)
    // foo: 13 (u64)
}Run

The status of this library

While this library is the standard way of working with JSON in Rust, there is a next-generation library called Serde that's in the works (it's faster, overcomes some design limitations of rustc-serialize and has more features). You might consider using it when starting a new project or evaluating Rust JSON performance.

Structs

AsJson
AsPrettyJson
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.

PrettyJson
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
EncoderError
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

as_json

Create an AsJson wrapper which can be used to print a value as JSON on-the-fly via write!

as_pretty_json

Create an AsPrettyJson wrapper which can be used to print a value as JSON on-the-fly via write!

decode

Shortcut function to decode a JSON &str into an object

encode

Shortcut function to encode a T into a JSON String

error_str

Returns a readable error string for a given error code.

Type Definitions

Array
BuilderError
DecodeResult
EncodeResult
Object