1 //! A [serde]-compatible [TOML]-parsing library
2 //!
3 //! TOML itself is a simple, ergonomic, and readable configuration format:
4 //!
5 //! ```toml
6 //! [package]
7 //! name = "toml"
8 //! version = "0.4.2"
9 //! authors = ["Alex Crichton <[email protected]>"]
10 //!
11 //! [dependencies]
12 //! serde = "1.0"
13 //! ```
14 //!
15 //! The TOML format tends to be relatively common throughout the Rust community
16 //! for configuration, notably being used by [Cargo], Rust's package manager.
17 //!
18 //! ## TOML values
19 //!
20 //! A TOML document is represented with the [`Table`] type which maps `String` to the [`Value`] enum:
21 //!
22 //! ```rust
23 //! # use toml::value::{Datetime, Array, Table};
24 //! pub enum Value {
25 //!     String(String),
26 //!     Integer(i64),
27 //!     Float(f64),
28 //!     Boolean(bool),
29 //!     Datetime(Datetime),
30 //!     Array(Array),
31 //!     Table(Table),
32 //! }
33 //! ```
34 //!
35 //! ## Parsing TOML
36 //!
37 //! The easiest way to parse a TOML document is via the [`Table`] type:
38 //!
39 #![cfg_attr(not(feature = "parse"), doc = " ```ignore")]
40 #![cfg_attr(feature = "parse", doc = " ```")]
41 //! use toml::Table;
42 //!
43 //! let value = "foo = 'bar'".parse::<Table>().unwrap();
44 //!
45 //! assert_eq!(value["foo"].as_str(), Some("bar"));
46 //! ```
47 //!
48 //! The [`Table`] type implements a number of convenience methods and
49 //! traits; the example above uses [`FromStr`] to parse a [`str`] into a
50 //! [`Table`].
51 //!
52 //! ## Deserialization and Serialization
53 //!
54 //! This crate supports [`serde`] 1.0 with a number of
55 //! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
56 //! `Serializer` traits. Namely, you'll find:
57 //!
58 //! * `Deserialize for Table`
59 //! * `Serialize for Table`
60 //! * `Deserialize for Value`
61 //! * `Serialize for Value`
62 //! * `Deserialize for Datetime`
63 //! * `Serialize for Datetime`
64 //! * `Deserializer for de::Deserializer`
65 //! * `Serializer for ser::Serializer`
66 //! * `Deserializer for Table`
67 //! * `Deserializer for Value`
68 //!
69 //! This means that you can use Serde to deserialize/serialize the
70 //! [`Table`] type as well as [`Value`] and [`Datetime`] type in this crate. You can also
71 //! use the [`Deserializer`], [`Serializer`], or [`Table`] type itself to act as
72 //! a deserializer/serializer for arbitrary types.
73 //!
74 //! An example of deserializing with TOML is:
75 //!
76 #![cfg_attr(not(feature = "parse"), doc = " ```ignore")]
77 #![cfg_attr(feature = "parse", doc = " ```")]
78 //! use serde::Deserialize;
79 //!
80 //! #[derive(Deserialize)]
81 //! struct Config {
82 //!     ip: String,
83 //!     port: Option<u16>,
84 //!     keys: Keys,
85 //! }
86 //!
87 //! #[derive(Deserialize)]
88 //! struct Keys {
89 //!     github: String,
90 //!     travis: Option<String>,
91 //! }
92 //!
93 //! let config: Config = toml::from_str(r#"
94 //!     ip = '127.0.0.1'
95 //!
96 //!     [keys]
97 //!     github = 'xxxxxxxxxxxxxxxxx'
98 //!     travis = 'yyyyyyyyyyyyyyyyy'
99 //! "#).unwrap();
100 //!
101 //! assert_eq!(config.ip, "127.0.0.1");
102 //! assert_eq!(config.port, None);
103 //! assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
104 //! assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
105 //! ```
106 //!
107 //! You can serialize types in a similar fashion:
108 //!
109 #![cfg_attr(not(feature = "display"), doc = " ```ignore")]
110 #![cfg_attr(feature = "display", doc = " ```")]
111 //! use serde::Serialize;
112 //!
113 //! #[derive(Serialize)]
114 //! struct Config {
115 //!     ip: String,
116 //!     port: Option<u16>,
117 //!     keys: Keys,
118 //! }
119 //!
120 //! #[derive(Serialize)]
121 //! struct Keys {
122 //!     github: String,
123 //!     travis: Option<String>,
124 //! }
125 //!
126 //! let config = Config {
127 //!     ip: "127.0.0.1".to_string(),
128 //!     port: None,
129 //!     keys: Keys {
130 //!         github: "xxxxxxxxxxxxxxxxx".to_string(),
131 //!         travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
132 //!     },
133 //! };
134 //!
135 //! let toml = toml::to_string(&config).unwrap();
136 //! ```
137 //!
138 //! [TOML]: https://github.com/toml-lang/toml
139 //! [Cargo]: https://crates.io/
140 //! [`serde`]: https://serde.rs/
141 //! [serde]: https://serde.rs/
142 
143 #![deny(missing_docs)]
144 #![warn(rust_2018_idioms)]
145 // Makes rustc abort compilation if there are any unsafe blocks in the crate.
146 // Presence of this annotation is picked up by tools such as cargo-geiger
147 // and lets them ensure that there is indeed no unsafe code as opposed to
148 // something they couldn't detect (e.g. unsafe added via macro expansion, etc).
149 #![forbid(unsafe_code)]
150 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
151 
152 pub mod map;
153 pub mod value;
154 
155 pub mod de;
156 pub mod ser;
157 
158 #[doc(hidden)]
159 pub mod macros;
160 
161 mod edit;
162 #[cfg(feature = "display")]
163 mod fmt;
164 mod table;
165 
166 #[cfg(feature = "parse")]
167 #[doc(inline)]
168 pub use crate::de::{from_str, Deserializer};
169 #[cfg(feature = "display")]
170 #[doc(inline)]
171 pub use crate::ser::{to_string, to_string_pretty, Serializer};
172 #[doc(inline)]
173 pub use crate::value::Value;
174 
175 pub use serde_spanned::Spanned;
176 pub use table::Table;
177 
178 // Shortcuts for the module doc-comment
179 #[allow(unused_imports)]
180 use core::str::FromStr;
181 #[allow(unused_imports)]
182 use toml_datetime::Datetime;
183