nop-json

Documentation crates.io

This is full-featured modern JSON implementation according to ECMA-404 standard.

This crate allows deserialization of JSON io::Read stream into primitive types (bool, i32, etc.), Strings and any other types that implement special trait called TryFromJson, which can be implemented automatically through #[derive(TryFromJson)] for your structs and enums.

And serialization back to JSON through DebugToJson trait, that acts like Debug, allowing to print your objects with println!() and such.

It allows to read whitespece-separated JSON values from stream in sequence. It also allows to pipe blob strings to a writer.

This implementation avoids unnecessary memory allocations and temporary object creations.

Installation

In Cargo.toml of your project add: toml [dependencies] nop-json = "1.0"

Creating the Reader object

First need to create a Reader object giving it something that implements Iterator<Item=u8>. We can read from a string like this:

```rust use nop_json::Reader;

let mut reader = Reader::new(r#" "a JSON string" "#.bytes()); ```

To read from a file we need to convert std::io::Read to Iterator<Item=u8>. We can use read_iter crate for this.

```rust use std::fs::File; use readiter::ReadIter; // also add dependency to Cargo.toml use nopjson::Reader;

let mut file = ReadIter::new(File::open("/tmp/test.json").unwrap()); let mut reader = Reader::new(&mut file); ```

See Reader::new() for more details.

Deserializing simple values

To read JSON values from the input stream, call reader.read() method, and assign the result to a variable that implements TryFromJson trait. This crate adds implementation of TryFromJson to many primitive types, Vec, HashMap, and more.

```rust use nop_json::Reader;

let mut reader = Reader::new(r#" true 100.5 "Hello" "Infinity" [true, false] "#.bytes());

let thetrue: bool = reader.read().unwrap(); let thehundredpointfive: f32 = reader.read().unwrap(); let thehello: String = reader.read().unwrap(); let theinfinity: f32 = reader.read().unwrap(); let the_array: Vec = reader.read().unwrap();

asserteq!(thetrue, true); asserteq!(thehundredpointfive, 100.5); asserteq!(thehello, "Hello"); assert!(theinfinity.isinfinite()); asserteq!(thearray, vec![true, false]); ```

Deserializing any JSON values

We have generic Value type that can hold any JSON node.

```rust use nop_json::{Reader, Value}; use std::convert::TryInto;

let mut reader = Reader::new(r#" true 100.5 "Hello" [true, false] "#.bytes());

let thetrue: Value = reader.read().unwrap(); let thehundredpointfive: Value = reader.read().unwrap(); let thehello: Value = reader.read().unwrap(); let thearray: Value = reader.read().unwrap();

asserteq!(thetrue, Value::Bool(true)); let thehundredpointfive: f32 = thehundredpointfive.tryinto().unwrap(); asserteq!(thehundredpointfive, 100.5f32); asserteq!(thehello, Value::String("Hello".tostring())); asserteq!(thearray, Value::Array(vec![Value::Bool(true), Value::Bool(false)])); ```

You can parse any JSON document to Value.

```rust use nop_json::{Reader, Value};

let mut reader = Reader::new(r#" {"array": [{"x": 1}, "a string"]} "#.bytes()); let doc: Value = reader.read().unwrap(); asserteq!(doc.tostring(), r#"{"array":[{"x":1},"a string"]}"#); ```

Deserializing/serializing structs and enums

To deserialize a struct or an enum, your struct needs to implement TryFromJson trait. To serialize - DebugToJson.

```rust use nop_json::{Reader, TryFromJson, DebugToJson};

[derive(TryFromJson, DebugToJson, PartialEq)]

struct Point {x: i32, y: i32}

[derive(TryFromJson, DebugToJson, PartialEq)]

enum Geometry { #[json(point)] Point(Point), #[json(cx, cy, r)] Circle(i32, i32, i32), Nothing, }

let mut reader = Reader::new(r#" {"point": {"x": 0, "y": 0}} "#.bytes()); let obj: Geometry = reader.read().unwrap(); println!("Serialized back to JSON: {:?}", obj); `` SeeTryFromJson,DebugToJson`.

Serializing scalar values

You can println!() word "true" or "false" to serialize a boolean. Also numbers can be printed as println!() does by default. The format is JSON-compatible. To serialize a &str, you can use escape function.

Alternatively you can create a Value object, and serialize it. ```rust use std::convert::TryInto; use nop_json::Value;

let thetrue: Value = true.tryinto().unwrap(); println!("Serialized to JSON: {:?}", the_true); ```

Skipping a value from stream

To skip current value without storing it (and allocating memory), read it to the () type. ```rust use nop_json::Reader;

let mut reader = Reader::new(r#" true 100.5 "Hello" [true, false] "#.bytes());

let _: () = reader.read().unwrap(); let _: () = reader.read().unwrap(); let _: () = reader.read().unwrap(); let _: () = reader.read().unwrap(); ```

Reading binary data

See read_blob.

License: MIT