Skip to content

Commit e3e3016

Browse files
committed
Updated README.md, closes #6
1 parent 0fb3777 commit e3e3016

File tree

1 file changed

+56
-39
lines changed

1 file changed

+56
-39
lines changed

README.md

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ types, object keys can change types between API calls or not include
1919
some keys under some conditions. Mapping that to idiomatic Rust structs
2020
introduces friction.
2121

22-
This crate intends to avoid that friction by extensively using static dispatch
23-
and hiding type information behind enums, while still giving you all the
24-
guarantees of safe Rust code.
22+
This crate intends to avoid that friction.
2523

2624
```rust
27-
let data = json::parse(r#"
25+
let parsed = json::parse(r#"
2826
2927
{
3028
"code": 200,
@@ -40,50 +38,59 @@ let data = json::parse(r#"
4038
4139
"#).unwrap();
4240

43-
assert!(data["code"] == 200);
44-
assert!(data["success"] == true));
45-
assert!(data["payload"]["features"].is_array());
46-
assert!(data["payload"]["features"][0] == "awesome");
47-
assert!(data["payload"]["features"].contains("easyAPI"));
41+
let instantiated = object!{
42+
"code" => 200,
43+
"success" => true,
44+
"payload" => object!{
45+
"features" => array![
46+
"awesome",
47+
"easyAPI",
48+
"lowLearningCurve"
49+
]
50+
}
51+
};
4852

49-
// Error resilient: non-existent values default to null
50-
assert!(data["this"]["does"]["not"]["exist"].is_null());
53+
assert_eq!(parsed, instantiated);
5154
```
5255

53-
## Create JSON data without defining structs
56+
## First class citizen
5457

55-
```rust
56-
#[macro_use]
57-
extern crate json;
58-
59-
fn main() {
60-
let data = object!{
61-
"a" => "bar",
62-
"b" => array![1, false, "foo"]
63-
};
64-
65-
assert_eq!(data.dump(), r#"{"a":"bar","b":[1,false,"foo"]}"#);
66-
}
67-
```
68-
69-
## Mutate simply by assigning new values
58+
Using macros and easy indexing, it's easy to work with the data.
7059

7160
```rust
72-
let mut data = json::parse(r#"
73-
74-
{
75-
"name": "Bob",
76-
"isAwesome": false
77-
}
78-
79-
"#).unwrap();
61+
let mut data = object!{
62+
"foo" => false,
63+
"bar" => json::Null,
64+
"answer" => 42,
65+
"list" => array![json::Null, "world", true]
66+
};
67+
68+
// Partial equality is implemented for most raw types:
69+
assert!(data["foo"] == false);
70+
71+
// And it's type aware, `null` and `false` are different values:
72+
assert!(data["bar"] != false);
73+
74+
// But you can use any Rust number types:
75+
assert!(data["answer"] == 42);
76+
assert!(data["answer"] == 42.0);
77+
assert!(data["answer"] == 42isize);
78+
79+
// Access nested structures, arrays and objects:
80+
assert!(data["list"][0].is_null());
81+
assert!(data["list"][1] == "world");
82+
assert!(data["list"][2] == true);
83+
84+
// Error resilient - accessing properties that don't exist yield null:
85+
assert!(data["this"]["does"]["not"]["exist"].is_null());
8086

81-
data["isAwesome"] = true.into();
82-
data["likes"] = "Rust".into();
87+
// Mutate by assigning:
88+
data["list"][0] = "Hello".into();
8389

84-
assert_eq!(data.dump(), r#"{"isAwesome":true,"likes":"Rust","name":"Bob"}"#);
90+
// Use the `dump` method to serialize the data:
91+
assert_eq!(data.dump(), r#"{"answer":42,"bar":null,"foo":false,"list":["Hello","world",true]}"#);
8592

86-
// Pretty print the output
93+
// Or pretty print it out:
8794
println!("{:#}", data);
8895
```
8996

@@ -102,3 +109,13 @@ Then import it in your `main.rs` / `lib.rs` file:
102109
#[macro_use]
103110
extern crate json;
104111
```
112+
113+
## Performance
114+
115+
While performance is not the main goal of this crate, it is still relevant, and it's doing pretty well in the company:
116+
117+
![](http://terhix.com/json-perf.png)
118+
119+
[The benchmarks](https://github.com/maciejhirsz/json-rust/blob/benches/benches/log.rs) were run on 2012 MacBook Air, your results may vary. Many thanks to @dtolnay for providing the baseline struct and test data the tests could be run on.
120+
121+
While this is not necessarily a be-all end-all benchmark, the main takeaway from this is that Serde parsing is much faster when parsing to a struct, since the parser knows exactly the kind of data it needs, and doesn't pay the (re)allocation costs of pushing data to a map. Also worth noting, rustc-serialize suffers since it first has to parse JSON to generic enum-based values, and only then map those onto structs.

0 commit comments

Comments
 (0)