deser_hj/lib.rs
1//! Parse [Hjson](https://hjson.github.io/) compatible with deser.
2//!
3//! Hjson is JSON for humans, a format for configuration files:
4//!
5//! * `#`, `//` and `/* */` comments,
6//! * commas between values are optional, commas after the last element of
7//! sequences and maps are allowed,
8//! * map keys without quotes (`name: api`), they end at whitespace and
9//! the punctuators `{}[],:`,
10//! * strings without quotes, which end at the end of the line (`note:
11//! runs until the end, #, and // too`),
12//! * multiline strings in triple single quotes (`'''`), the indentation up
13//! to the column of the opening quotes is removed,
14//! * strings in single quotes,
15//! * the braces of a map at the root can be omitted.
16//!
17//! Numbers, `true`, `false` and `null` without quotes are values only if
18//! nothing but whitespace, a comma, the end of a container or a comment
19//! follows them on the line: `5 # minutes` is the number `5`, `5 minutes`
20//! is a string. Their type is inferred from their text, so they are
21//! passed on as [`Implicit`](deser_core::Implicit) values: an `u16`
22//! receives `8080` as number, a `String` as `"8080"`.
23//!
24//! Otherwise this works like [`deser-json`](https://docs.rs/deser-json):
25//! strings and keys without escape sequences are borrowed from the input and
26//! the positions of errors and values refer to the input. In [JSON
27//! Lines](Trailing::Newline) every line break ends a value. The parser passes the [Hjson test
28//! suite](https://github.com/hjson/hjson/tree/master/testCases).
29//!
30//! ```rust
31//! #[derive(deser::Deserialize)]
32//! struct Config<'a> {
33//! name: &'a str,
34//! version: String,
35//! ports: Vec<u16>,
36//! motd: String,
37//! }
38//!
39//! let config: Config = deser_hj::from_str(r#"
40//! ## the name of the service
41//! name: api
42//! version: 2
43//! ports: [80, 443]
44//! motd:
45//! '''
46//! Welcome!
47//! Have a nice day.
48//! '''
49//! "#).unwrap();
50//! assert_eq!(config.name, "api");
51//! assert_eq!(config.version, "2");
52//! assert_eq!(config.ports, [80, 443]);
53//! assert_eq!(config.motd, "Welcome!\nHave a nice day.");
54//! ```
55//!
56//! JSON is valid Hjson, so values are serialized as JSON (with the same
57//! serializer as `deser-json`).
58//!
59//! # Features
60//!
61//! * `io` (enabled by default): reading and writing streams of the
62//! standard library (with `DeserializerConfig::reader`). Requires
63//! `std`.
64//! * `speedups` (enabled by default): faster UTF-8 validation.
65//! * `std` (enabled by default): uses the standard library. Without it
66//! this crate only needs `alloc` (see [`no_std`](https://docs.rs/deser/latest/deser/#no_std)).
67#![doc(html_logo_url = "https://raw.githubusercontent.com/mitsuhiko/deser/main/artwork/logo.svg")]
68#![cfg_attr(not(any(feature = "std", test)), no_std)]
69
70extern crate alloc;
71
72// These are generated from `deser-template-json`.
73mod buf;
74mod copy;
75mod de;
76mod escape;
77mod parser;
78mod pretty;
79mod scan;
80mod ser;
81mod stream;
82mod trailing;
83
84pub use self::de::{
85 Deserializer, DeserializerConfig, DeserializerConfigBuilder, Iter, from_slice, from_str,
86};
87#[cfg(feature = "io")]
88pub use self::ser::to_writer;
89pub use self::ser::{
90 Indent, InlinePolicy, Serializer, SerializerConfig, SerializerConfigBuilder, to_string,
91};
92pub use self::stream::StreamDeserializer;
93#[cfg(feature = "io")]
94pub use self::stream::from_reader;
95pub use self::trailing::Trailing;