Module rustc_serialize::json
source · Expand description
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):
I64
: equivalent to rust’si64
U64
: equivalent to rust’su64
F64
: equivalent to rust’sf64
Boolean
: equivalent to rust’sbool
String
: equivalent to rust’sString
Array
: equivalent to rust’sVec<T>
, but also allowing objects of different types in the same arrayObject
: equivalent to rust’sBTreeMap<String, json::Json>
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,
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"
]
}
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();
}
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"};
}
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();
}
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)
}
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
- A Builder consumes a json::Parser to create a generic Json structure.
- A structure to decode JSON to values in rust.
- A structure for implementing serialization to JSON.
- A streaming JSON parser implemented as an iterator of JsonEvent, consuming an iterator of char.
- A Stack represents the current position of the parser in the logical structure of the JSON stream. For example foo.bar[3].x
Enums
- The errors that can arise while parsing a JSON stream.
- Represents a json value
- The output of the streaming parser.
- 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
- A trait for converting values to JSON
Functions
- Create an
AsJson
wrapper which can be used to print a value as JSON on-the-fly viawrite!
- Create an
AsPrettyJson
wrapper which can be used to print a value as JSON on-the-fly viawrite!
- Shortcut function to decode a JSON
&str
into an object - Shortcut function to encode a
T
into a JSONString
- Returns a readable error string for a given error code.