json5/
lib.rs

1//! JSON5 is a superset of [JSON][] with an expanded syntax including some productions from
2//! [ECMAScript 5.1][].
3//!
4//! In particular, JSON5 allows comments, trailing commas, object keys without quotes, single
5//! quoted strings and more. See the [JSON5 project page][] for full details.
6//!
7//! ```json5,ignore
8//! {
9//!   // comments
10//!   unquoted: 'and you can quote me on that',
11//!   singleQuotes: 'I can use "double quotes" here',
12//!   lineBreaks: "Look, Mom! \
13//! No \\n's!",
14//!   hexadecimal: 0xdecaf,
15//!   leadingDecimalPoint: .8675309, andTrailing: 8675309.,
16//!   positiveSign: +1,
17//!   trailingComma: 'in objects', andIn: ['arrays',],
18//!   "backwardsCompatible": "with JSON",
19//! }
20//! ```
21//!
22//! This crate provides functions for deserializing JSON5 text into a Rust datatype and for
23//! serializing a Rust datatype as JSON5 text, both via the [Serde framework][].
24//!
25//! # Deserialization
26//!
27//! Implementing Serde’s [`Deserialize`][] trait on your type will allow you to parse JSON5
28//! text into a value of that type with [`from_str`][].
29//!
30//! ```rust
31//! use serde_derive::Deserialize;
32//!
33//! #[derive(Deserialize, Debug, PartialEq)]
34//! struct Config {
35//!     message: String,
36//!     n: i32,
37//! }
38//!
39//! let config = "
40//!     {
41//!       // A traditional message.
42//!       message: 'hello world',
43//!
44//!       // A number for some reason.
45//!       n: 42,
46//!     }
47//! ";
48//!
49//! assert_eq!(
50//!     json5::from_str(config),
51//!     Ok(Config {
52//!         message: "hello world".to_string(),
53//!         n: 42,
54//!     }),
55//! );
56//! ```
57//!
58//! Also, you could deserialize into serde_json::Value
59//!
60//! ```rust
61//! use json5;
62//! use serde_json::{Value, json};
63//!
64//! let config = "
65//!     {
66//!       // A traditional message.
67//!       message: 'hello world',
68//!
69//!       // A number for some reason.
70//!       n: 42,
71//!     }
72//! ";
73//!
74//! assert_eq!(
75//!     json5::from_str::<Value>(&config),
76//!     Ok(json!({
77//!         "message": "hello world",
78//!         "n": 42
79//!     }))
80//! );
81//! ```
82//!
83//! There are many ways to customize the deserialization (e.g. deserializing `camelCase` field
84//! names into a struct with `snake_case` fields). See the Serde docs, especially the
85//! [Attributes][], [Custom serialization][] and [Examples][] sections.
86//!
87//! # Serialization
88//!
89//! Similarly, implementing [`Serialize`][] on a Rust type allows you to produce a JSON5
90//! serialization of values of that type with [`to_string`][]. At present the serializer will just
91//! produce JSON (since it's a valid subset of JSON5), but future work will allow specifying the
92//! output style (single over double quotes, trailing commas, indentation etc.).
93//!
94//! ```rust
95//! use serde_derive::Serialize;
96//! use std::collections::HashMap;
97//!
98//! #[derive(Serialize, Debug)]
99//! #[serde(untagged)]
100//! enum Val {
101//!     Null,
102//!     Bool(bool),
103//!     Number(f64),
104//!     String(String),
105//!     Array(Vec<Val>),
106//!     Object(HashMap<String, Val>),
107//! }
108//! let mut map = HashMap::new();
109//! map.insert(
110//!     "a".to_owned(),
111//!     Val::Array(vec![
112//!         Val::Null,
113//!         Val::Bool(true),
114//!         Val::Number(42.),
115//!         Val::Number(42.42),
116//!         Val::Number(f64::NAN),
117//!         Val::String("hello".to_owned()),
118//!     ])
119//! );
120//! assert_eq!(
121//!     json5::to_string(&Val::Object(map)),
122//!     Ok("{\"a\":[null,true,42,42.42,NaN,\"hello\"]}".to_owned()),
123//! )
124//! ```
125//!
126//! You could also build from serde_json
127//!
128//! ```rust
129//! use serde_json::{json, Value, Map, Number};
130//! assert_eq!(
131//!     json5::to_string(
132//!         &json!({"a": [null, true, 42, 42.42, f64::NAN, "hello"]})
133//!     ),
134//!     Ok("{\"a\":[null,true,42,42.42,null,\"hello\"]}".to_owned())
135//! );
136//! let mut map = Map::new();
137//! map.insert(
138//!     "a".to_owned(),
139//!     Value::Array(vec![
140//!         Value::Null,
141//!         Value::Bool(true),
142//!         Value::Number(Number::from_f64(42.).unwrap()),
143//!         Value::Number(Number::from_f64(42.42).unwrap()),
144//!         Value::String("hello".to_owned()),
145//!     ])
146//! );
147//! assert_eq!(
148//!     json5::to_string(&Value::Object(map)),
149//!     Ok("{\"a\":[null,true,42,42.42,\"hello\"]}".to_owned()),
150//! )
151//! ```
152//!
153//! There are many ways to customize the serialization (e.g. serializing `snake_case` struct fields
154//! as `camelCase`). See the Serde docs, especially the [Attributes][], [Custom serialization][]
155//! and [Examples][] sections.
156//!
157//! # Limitations
158//!
159//! At the time of writing the following is unsupported:
160//!
161//! - deserializing into borrowed types (e.g. fields of type `&str`)
162//!
163//! - serializing or deserializing [byte arrays][]
164//!
165//! - specifying the style of JSON5 output from the serializer (single over double quotes, trailing
166//! commas, indentation etc.)
167//!
168//! [JSON]: https://tools.ietf.org/html/rfc7159
169//! [ECMAScript 5.1]: https://www.ecma-international.org/ecma-262/5.1/
170//! [JSON5 project page]: https://json5.org/
171//! [Serde framework]: https://serde.rs/
172//! [`Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
173//! [`from_str`]: fn.from_str.html
174//! [Attributes]: https://serde.rs/attributes.html
175//! [Custom serialization]: https://serde.rs/custom-serialization.html
176//! [Examples]: https://serde.rs/examples.html
177//! [`Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
178//! [`to_string`]: fn.to_string.html
179//! [byte arrays]: https://serde.rs/data-model.html#types
180
181#![warn(missing_docs)]
182#![warn(rust_2018_idioms)]
183
184mod de;
185mod error;
186mod ser;
187
188pub use crate::de::{from_str, Deserializer};
189pub use crate::error::{Error, Location, Result};
190pub use crate::ser::to_string;