mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-27 22:00:17 +00:00
JSON rust implementation recipe
This commit is contained in:
parent
28245801d5
commit
71fb77af9b
3 changed files with 43 additions and 98 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"json 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -67,6 +68,11 @@ name = "getopts"
|
|||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "json"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
|
@ -138,6 +144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46"
|
||||
"checksum gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
|
||||
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
|
||||
"checksum json 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7eb285e773498f9473a6e2255feffe95db9c55579c7931a6db83c9e02a4673"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
|
||||
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
|
||||
|
|
|
@ -8,6 +8,7 @@ build = "build.rs"
|
|||
[dependencies]
|
||||
byteorder = "1.0.0"
|
||||
error-chain = "0.8.0"
|
||||
json = "0.11.5"
|
||||
|
||||
[build-dependencies]
|
||||
skeptic = "0.6"
|
||||
|
|
133
README.md
133
README.md
|
@ -1,117 +1,54 @@
|
|||
# Cookin' with Rust
|
||||
#JSON
|
||||
|
||||
A practical guide to the Rust crate ecosystem.
|
||||
|
||||
- [Read and write integers in little-endian byte order](#byteorder)
|
||||
[![byteorder][byteorder-badge]][byteorder]
|
||||
##JSON implementation in Rust:
|
||||
|
||||
|
||||
# A note about error handling
|
||||
[![json][json-badge]][json]
|
||||
|
||||
Error handling in Rust is robust when done correctly, but in today's
|
||||
Rust it requires a fair bit of boilerplate. Because of this one often
|
||||
seees Rust examples filled with `unwrap` calls instead of proper error
|
||||
handling.
|
||||
|
||||
Since these recipes are intended to be reused as-is and encourage best
|
||||
practices, they set up error handling correctly, and when necessary to
|
||||
reduce boilerplate, they use the [error-chain] crate.
|
||||
|
||||
The code for this setup generally looks like:
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod errors {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
#[macro_use]
|
||||
extern crate json;
|
||||
|
||||
fn main() {
|
||||
|
||||
let parsed = json::parse(r#"
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"success": true,
|
||||
"payload": {
|
||||
"features": [
|
||||
"awesome",
|
||||
"easyAPI",
|
||||
"lowLearningCurve"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
use errors::*;
|
||||
"#).unwrap();
|
||||
|
||||
fn main() { run().unwrap() }
|
||||
|
||||
fn run() -> Result<()> {
|
||||
use std::io::Write;
|
||||
let ref mut stdout = ::std::io::stdout();
|
||||
writeln!(stdout, "hello, world")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
This is using the `error_chain!` macro to define a custom `Error`
|
||||
and `Result` type, along with an automatic conversion from
|
||||
the common `::std::io::Error` type. The automatic conversion
|
||||
makes the `?` operator work
|
||||
|
||||
For more background on error handling in Rust, read TODO and TODO.
|
||||
|
||||
|
||||
<a id="byteorder"></a>
|
||||
## Read and write integers in little-endian byte order
|
||||
|
||||
[![byteorder][byteorder-badge]][byteorder]
|
||||
|
||||
```rust
|
||||
extern crate byteorder;
|
||||
|
||||
use std::io::Cursor;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
#[derive(Default, Eq, PartialEq, Debug)]
|
||||
struct Payload {
|
||||
kind: u8,
|
||||
value: u16,
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let original_payload = Payload::default();
|
||||
let encoded_buf = encode(&original_payload)?;
|
||||
let decoded_payload = decode(&encoded_buf)?;
|
||||
assert_eq!(original_payload, decoded_payload);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encode(payload: &Payload) -> Result<Vec<u8>> {
|
||||
let mut wtr = vec![];
|
||||
wtr.write_u8(payload.kind)?;
|
||||
wtr.write_u16::<LittleEndian>(payload.value)?;
|
||||
Ok(wtr)
|
||||
}
|
||||
|
||||
fn decode(buf: &[u8]) -> Result<Payload> {
|
||||
let mut rdr = Cursor::new(buf);
|
||||
Ok(Payload {
|
||||
kind: rdr.read_u8()?,
|
||||
value: rdr.read_u16::<LittleEndian>()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
mod errors {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
}
|
||||
let instantiated = object!{
|
||||
"code" => 200,
|
||||
"success" => true,
|
||||
"payload" => object!{
|
||||
"features" => array![
|
||||
"awesome",
|
||||
"easyAPI",
|
||||
"lowLearningCurve"
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(parsed, instantiated);
|
||||
|
||||
}
|
||||
use errors::*;
|
||||
fn main() { run().unwrap() }
|
||||
```
|
||||
|
||||
|
||||
# License
|
||||
|
||||
MIT/Apache-2.0
|
||||
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[byteorder-badge]: https://img.shields.io/crates/v/rustc-serialize.svg
|
||||
[byteorder]: https://docs.rs/byteorder
|
||||
[json-badge]: https://img.shields.io/crates/v/rustc-serialize.svg
|
||||
[json]: http://json.rs/doc/json/
|
||||
|
|
Loading…
Reference in a new issue