jsonc_parser/lib.rs
1//! # jsonc-parser
2//!
3//! A JSON parser and manipulator that supports comments and other JSON extensions.
4//!
5//! ## Parsing
6//!
7//! To a simple `JsonValue`:
8//!
9//! ```
10//! use jsonc_parser::parse_to_value;
11//!
12//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
13//! let json_value = parse_to_value(r#"{ "test": 5 } // test"#, &Default::default())?;
14//! // check the json_value here
15//! # Ok(())
16//! # }
17//! ```
18//!
19//! Or an AST:
20//!
21//! ```
22//! use jsonc_parser::parse_to_ast;
23//! use jsonc_parser::CollectOptions;
24//! use jsonc_parser::CommentCollectionStrategy;
25//!
26//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
27//! let parse_result = parse_to_ast(r#"{ "test": 5 } // test"#, &CollectOptions {
28//! comments: CommentCollectionStrategy::Separate, // include comments in result
29//! tokens: true, // include tokens in result
30//! }, &Default::default())?;
31//! // ...inspect parse_result for value, tokens, and comments here...
32//! # Ok(())
33//! # }
34//! ```
35//!
36//! ## Manipulation (CST)
37//!
38//! When enabling the `cst` cargo feature, parsing to a CST provides a first class manipulation API:
39//!
40//! ```
41//! # #[cfg(feature = "cst")]
42//! # {
43//! use jsonc_parser::cst::CstRootNode;
44//! use jsonc_parser::ParseOptions;
45//! use jsonc_parser::json;
46//!
47//! let json_text = r#"{
48//! // comment
49//! "data": 123
50//! }"#;
51//!
52//! let root = CstRootNode::parse(json_text, &ParseOptions::default()).unwrap();
53//! let root_obj = root.object_value_or_set();
54//!
55//! root_obj.get("data").unwrap().set_value(json!({
56//! "nested": true
57//! }));
58//! root_obj.append("new_key", json!([456, 789, false]));
59//!
60//! assert_eq!(root.to_string(), r#"{
61//! // comment
62//! "data": {
63//! "nested": true
64//! },
65//! "new_key": [456, 789, false]
66//! }"#);
67//! # }
68//! ```
69//!
70//! ## Serde
71//!
72//! If you enable the `"serde"` feature as follows:
73//!
74//! ```toml
75//! # in Cargo.toml
76//! jsonc-parser = { version = "...", features = ["serde"] }
77//! ```
78//!
79//! Then you can use the `parse_to_serde_value` function to deserialize JSONC directly into
80//! any type implementing `serde::Deserialize`:
81//!
82//! ```
83//! # #[cfg(feature = "serde")]
84//! # {
85//! use jsonc_parser::parse_to_serde_value;
86//!
87//! #[derive(serde::Deserialize)]
88//! struct Config {
89//! test: u32,
90//! }
91//!
92//! # fn parse_example() -> Result<(), Box<dyn std::error::Error>> {
93//! let config: Config = parse_to_serde_value(r#"{ "test": 5 } // test"#, &Default::default())?;
94//! # Ok(())
95//! # }
96//! # }
97//! ```
98//!
99//! ## Parse Strictly as JSON
100//!
101//! By default this library is extremely loose in what it allows parsing. To be strict,
102//! provide `ParseOptions` and set all the options to false:
103//!
104//! ```
105//! use jsonc_parser::parse_to_value;
106//! use jsonc_parser::ParseOptions;
107//!
108//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
109//! # let text = "{}";
110//! let json_value = parse_to_value(text, &ParseOptions {
111//! allow_comments: false,
112//! allow_loose_object_property_names: false,
113//! allow_trailing_commas: false,
114//! allow_missing_commas: false,
115//! allow_single_quoted_strings: false,
116//! allow_hexadecimal_numbers: false,
117//! allow_unary_plus_numbers: false,
118//! })?;
119//! # Ok(())
120//! # }
121//! ```
122//!
123//! ## Error column number with unicode-width
124//!
125//! To get more accurate display column numbers in error messages, enable the `error_unicode_width` cargo feature,
126//! which will pull in and use the [unicode-width](https://crates.io/crates/unicode-width) dependency internally.
127//! Otherwise it will use the character count, which isn't as accurate of a number, but will probably be good enough
128//! in most cases.
129//!
130//! ## Faster hashing
131//!
132//! Parsed objects are stored in a hash map that uses the standard library's default (DoS-resistant but slower)
133//! hasher. When parsing trusted input, enable the `fast_hash` cargo feature to instead use the faster
134//! [rustc-hash](https://crates.io/crates/rustc-hash) hasher, which can noticeably speed up parsing of
135//! object-heavy documents:
136//!
137//! ```toml
138//! # in Cargo.toml
139//! jsonc-parser = { version = "...", features = ["fast_hash"] }
140//! ```
141//!
142//! This hasher is not resistant to hash-collision denial-of-service attacks, so avoid it when parsing
143//! untrusted input. It composes with the `preserve_order` feature.
144
145#![deny(clippy::print_stderr)]
146#![deny(clippy::print_stdout)]
147#![allow(clippy::uninlined_format_args)]
148
149pub mod ast;
150pub mod common;
151#[cfg(feature = "cst")]
152pub mod cst;
153pub mod errors;
154pub mod map;
155mod parse_to_ast;
156mod parse_to_value;
157mod parser;
158mod scanner;
159#[cfg(feature = "serde")]
160mod serde;
161mod string;
162pub mod tokens;
163mod value;
164
165pub use map::Map;
166pub use parse_to_ast::*;
167pub use parse_to_value::*;
168pub use scanner::*;
169pub use string::ParseStringErrorKind;
170pub use value::*;
171
172#[cfg(feature = "serde")]
173pub use serde::*;