nop_json/
lib.rs

1//! This is full-featured modern JSON implementation according to ECMA-404 standard.
2//!
3//! This crate allows deserialization of JSON `Iterator<u8>` stream into primitive types (`bool`, `i32`, etc.),
4//! Strings and any other types that implement special trait called [TryFromJson](trait.TryFromJson.html), which can be implemented
5//! automatically through `#[derive(TryFromJson)]` for your structs and enums.
6//!
7//! And serialization back to JSON through [DebugToJson](trait.DebugToJson.html) trait, that acts like [Debug](https://doc.rust-lang.org/std/fmt/trait.Debug.html), allowing to
8//! print your objects with `println!()` and such. Or through [WriteToJson](trait.WriteToJson.html) trait that allows to write
9//! to a `io::Write` stream.
10//!
11//! This crate allows to read whitespece-separated JSON values from stream in sequence. It also allows to pipe blob strings to a writer.
12//!
13//! # Installation
14//!
15//! In `Cargo.toml` of your project add:
16//!
17//! ```toml
18//! [dependencies]
19//! nop-json = "2.0"
20//! ```
21//!
22//! # Examples
23//!
24//! ## Creating Reader object
25//!
26//! First need to create a [Reader](struct.Reader.html) object giving it something that implements `Iterator<Item=u8>`.
27//! We can read from a string like this:
28//!
29//! ```
30//! use nop_json::Reader;
31//!
32//! let mut reader = Reader::new(r#" "a JSON string" "#.bytes());
33//! ```
34//!
35//! To read from a file we need to convert `std::io::Read` to `Iterator<Item=u8>`. We can use `read_iter` crate for this.
36//!
37//! ```no_run
38//! use std::fs::File;
39//! use read_iter::ReadIter; // also add dependency to Cargo.toml
40//! use nop_json::Reader;
41//!
42//! let mut file = ReadIter::new(File::open("/tmp/test.json").unwrap());
43//! let mut reader = Reader::new(&mut file);
44//! ```
45//!
46//! See [Reader::new()](struct.Reader.html#method.new) for more details.
47//!
48//! ## Deserializing simple values
49//!
50//! To read JSON values from an input stream, call `reader.read()` method, and assign the result to a variable that implements `TryFromJson`.
51//! This crate adds implementation of `TryFromJson` to many primitive types, `Vec`, `HashMap`, and more.
52//!
53//! ```
54//! use nop_json::Reader;
55//!
56//! let mut reader = Reader::new(r#" true  100.5  "Hello"  "Infinity"  [true, false] "#.bytes());
57//!
58//! let the_true: bool = reader.read().unwrap();
59//! let the_hundred_point_five: f32 = reader.read().unwrap();
60//! let the_hello: String = reader.read().unwrap();
61//! let the_infinity: f32 = reader.read().unwrap();
62//! let the_array: Vec<bool> = reader.read().unwrap();
63//!
64//! assert_eq!(the_true, true);
65//! assert_eq!(the_hundred_point_five, 100.5);
66//! assert_eq!(the_hello, "Hello");
67//! assert!(the_infinity.is_infinite());
68//! assert_eq!(the_array, vec![true, false]);
69//! ```
70//!
71//! ## Deserializing any JSON values
72//!
73//! We have generic [Value](enum.Value.html) type that can hold any JSON node.
74//!
75//! ```
76//! use nop_json::{Reader, Value};
77//! use std::convert::TryInto;
78//!
79//! let mut reader = Reader::new(r#" true  100.5  "Hello"  [true, false] "#.bytes());
80//!
81//! let the_true: Value = reader.read().unwrap();
82//! let the_hundred_point_five: Value = reader.read().unwrap();
83//! let the_hello: Value = reader.read().unwrap();
84//! let the_array: Value = reader.read().unwrap();
85//!
86//! assert_eq!(the_true, Value::Bool(true));
87//! let the_hundred_point_five: f32 = the_hundred_point_five.try_into().unwrap();
88//! assert_eq!(the_hundred_point_five, 100.5f32);
89//! assert_eq!(the_hello, Value::String("Hello".to_string()));
90//! assert_eq!(the_array, Value::Array(vec![Value::Bool(true), Value::Bool(false)]));
91//! ```
92//!
93//! You can parse any JSON document to [Value](enum.Value.html).
94//!
95//! ```
96//! use nop_json::{Reader, Value};
97//!
98//! let mut reader = Reader::new(r#" {"array": [{"x": 1}, "a string"]} "#.bytes());
99//! let doc: Value = reader.read().unwrap();
100//! assert_eq!(doc.to_string(), r#"{"array":[{"x":1},"a string"]}"#);
101//! ```
102//!
103//! ## Deserializing/serializing structs and enums
104//!
105//! To deserialize a struct or an enum, your struct needs to implement [TryFromJson](trait.TryFromJson.html) and [ValidateJson](trait.ValidateJson.html) traits.
106//! To serialize - [DebugToJson](trait.DebugToJson.html) and/or [WriteToJson](trait.WriteToJson.html).
107//!
108//! ```
109//! use nop_json::{Reader, TryFromJson, ValidateJson, DebugToJson};
110//!
111//! #[derive(TryFromJson, ValidateJson, DebugToJson, PartialEq)]
112//! struct Point {x: i32, y: i32}
113//!
114//! #[derive(TryFromJson, ValidateJson, DebugToJson, PartialEq)]
115//! enum Geometry
116//! {	#[json(point)] Point(Point),
117//! 	#[json(cx, cy, r)] Circle(i32, i32, i32),
118//! 	Nothing,
119//! }
120//!
121//! let mut reader = Reader::new(r#" {"point": {"x": 0, "y": 0}} "#.bytes());
122//! let obj: Geometry = reader.read().unwrap();
123//! println!("Serialized back to JSON: {:?}", obj);
124//! ```
125//! See [TryFromJson](trait.TryFromJson.html), [ValidateJson](trait.ValidateJson.html), [DebugToJson](trait.DebugToJson.html), [WriteToJson](trait.WriteToJson.html).
126//!
127//! ## Serializing scalar values
128//!
129//! You can println!() word "true" or "false" to serialize a boolean. Also numbers can be printed as println!() does by default.
130//! The format is JSON-compatible. To serialize a &str, you can use [escape](fn.escape.html) function.
131//!
132//! Alternatively you can create a [Value](enum.Value.html) object, and serialize with it any scalar/nonscalar value.
133//! ```
134//! use std::convert::TryInto;
135//! use nop_json::Value;
136//!
137//! let the_true: Value = true.try_into().unwrap();
138//! println!("Serialized to JSON: {:?}", the_true);
139//! # assert_eq!(format!("{:?}", the_true), "true")
140//! ```
141//!
142//! ## Skipping a value from stream
143//!
144//! To skip current value without storing it (and allocating memory), read it to the `()` type.
145//! ```
146//! use nop_json::Reader;
147//!
148//! let mut reader = Reader::new(r#" true  100.5  "Hello"  [true, false] "#.bytes());
149//!
150//! let _: () = reader.read().unwrap();
151//! let _: () = reader.read().unwrap();
152//! let _: () = reader.read().unwrap();
153//! let _: () = reader.read().unwrap();
154//! ```
155//!
156//! ## Reading binary data
157//! See [read_blob](struct.Reader.html#method.read_blob).
158//!
159//! ## Null, NaN, infinity and -0
160//!
161//! Reading to a variable of type `Option<T>` can read either `T` or `null`.
162//!
163//! ```
164//! use nop_json::Reader;
165//!
166//! let mut reader = Reader::new(r#" "non-null"  null "#.bytes());
167//!
168//! let str_or_null_1: Option<String> = reader.read().unwrap();
169//! let str_or_null_2: Option<String> = reader.read().unwrap();
170//!
171//! assert_eq!(str_or_null_1, Some("non-null".to_string()));
172//! assert_eq!(str_or_null_2, None);
173//! ```
174//!
175//! Reading junk to `f32` or `f64` type will read NaN. Reading string "Infinity", "-Infinity" and "-0" will read corresponding floating point numbers.
176//!
177//! ```
178//! use nop_json::Reader;
179//!
180//! let mut reader = Reader::new(r#" "Hello all!"  "Infinity"  "-Infinity"  "0"  "-0" "#.bytes());
181//!
182//! let nan: f32 = reader.read().unwrap();
183//! let inf: f32 = reader.read().unwrap();
184//! let minf: f32 = reader.read().unwrap();
185//! let zero: f32 = reader.read().unwrap();
186//! let mzero: f32 = reader.read().unwrap();
187//!
188//! assert!(nan.is_nan());
189//! assert_eq!(inf, f32::INFINITY);
190//! assert_eq!(minf, f32::NEG_INFINITY);
191//! assert!(zero==0.0 && !zero.is_sign_negative());
192//! assert!(mzero==0.0 && mzero.is_sign_negative());
193//! ```
194
195mod nop_json;
196mod value;
197mod debug_to_json;
198mod write_to_json;
199mod validate_json;
200mod escape;
201
202pub use crate::nop_json::{Reader, TryFromJson};
203pub use crate::debug_to_json::DebugToJson;
204pub use crate::write_to_json::WriteToJson;
205pub use crate::validate_json::ValidateJson;
206pub use crate::escape::{escape, escape_bytes};
207pub use value::Value;