Skip to main content

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;