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 <alex@alexcrichton.com>"] |
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 value in TOML is represented with the [`Value`] enum in this crate: |
21 | //! |
22 | //! ```rust,ignore |
23 | //! pub enum Value { |
24 | //! String(String), |
25 | //! Integer(i64), |
26 | //! Float(f64), |
27 | //! Boolean(bool), |
28 | //! Datetime(Datetime), |
29 | //! Array(Array), |
30 | //! Table(Table), |
31 | //! } |
32 | //! ``` |
33 | //! |
34 | //! TOML is similar to JSON with the notable addition of a [`Datetime`] |
35 | //! type. In general, TOML and JSON are interchangeable in terms of |
36 | //! formats. |
37 | //! |
38 | //! ## Parsing TOML |
39 | //! |
40 | //! The easiest way to parse a TOML document is via the [`Value`] type: |
41 | //! |
42 | //! ```rust |
43 | //! use toml::Value; |
44 | //! |
45 | //! let value = "foo = 'bar'" .parse::<Value>().unwrap(); |
46 | //! |
47 | //! assert_eq!(value["foo" ].as_str(), Some("bar" )); |
48 | //! ``` |
49 | //! |
50 | //! The [`Value`] type implements a number of convenience methods and |
51 | //! traits; the example above uses [`FromStr`] to parse a [`str`] into a |
52 | //! [`Value`]. |
53 | //! |
54 | //! ## Deserialization and Serialization |
55 | //! |
56 | //! This crate supports [`serde`] 1.0 with a number of |
57 | //! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and |
58 | //! `Serializer` traits. Namely, you'll find: |
59 | //! |
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 Value` |
67 | //! |
68 | //! This means that you can use Serde to deserialize/serialize the |
69 | //! [`Value`] type as well as the [`Datetime`] type in this crate. You can also |
70 | //! use the [`Deserializer`], [`Serializer`], or [`Value`] type itself to act as |
71 | //! a deserializer/serializer for arbitrary types. |
72 | //! |
73 | //! An example of deserializing with TOML is: |
74 | //! |
75 | //! ```rust |
76 | //! use serde_derive::Deserialize; |
77 | //! |
78 | //! #[derive(Deserialize)] |
79 | //! struct Config { |
80 | //! ip: String, |
81 | //! port: Option<u16>, |
82 | //! keys: Keys, |
83 | //! } |
84 | //! |
85 | //! #[derive(Deserialize)] |
86 | //! struct Keys { |
87 | //! github: String, |
88 | //! travis: Option<String>, |
89 | //! } |
90 | //! |
91 | //! fn main() { |
92 | //! let config: Config = toml::from_str(r#" |
93 | //! ip = '127.0.0.1' |
94 | //! |
95 | //! [keys] |
96 | //! github = 'xxxxxxxxxxxxxxxxx' |
97 | //! travis = 'yyyyyyyyyyyyyyyyy' |
98 | //! "# ).unwrap(); |
99 | //! |
100 | //! assert_eq!(config.ip, "127.0.0.1" ); |
101 | //! assert_eq!(config.port, None); |
102 | //! assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx" ); |
103 | //! assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy" ); |
104 | //! } |
105 | //! ``` |
106 | //! |
107 | //! You can serialize types in a similar fashion: |
108 | //! |
109 | //! ```rust |
110 | //! use serde_derive::Serialize; |
111 | //! |
112 | //! #[derive(Serialize)] |
113 | //! struct Config { |
114 | //! ip: String, |
115 | //! port: Option<u16>, |
116 | //! keys: Keys, |
117 | //! } |
118 | //! |
119 | //! #[derive(Serialize)] |
120 | //! struct Keys { |
121 | //! github: String, |
122 | //! travis: Option<String>, |
123 | //! } |
124 | //! |
125 | //! fn main() { |
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 | //! |
139 | //! [TOML]: https://github.com/toml-lang/toml |
140 | //! [Cargo]: https://crates.io/ |
141 | //! [`serde`]: https://serde.rs/ |
142 | //! [serde]: https://serde.rs/ |
143 | |
144 | #![deny (missing_docs)] |
145 | #![warn (rust_2018_idioms)] |
146 | // Makes rustc abort compilation if there are any unsafe blocks in the crate. |
147 | // Presence of this annotation is picked up by tools such as cargo-geiger |
148 | // and lets them ensure that there is indeed no unsafe code as opposed to |
149 | // something they couldn't detect (e.g. unsafe added via macro expansion, etc). |
150 | #![forbid (unsafe_code)] |
151 | |
152 | pub mod map; |
153 | pub mod value; |
154 | #[doc (no_inline)] |
155 | pub use crate::value::Value; |
156 | mod datetime; |
157 | |
158 | pub mod ser; |
159 | #[doc (no_inline)] |
160 | pub use crate::ser::{to_string, to_string_pretty, to_vec, Serializer}; |
161 | pub mod de; |
162 | #[doc (no_inline)] |
163 | pub use crate::de::{from_slice, from_str, Deserializer}; |
164 | mod tokens; |
165 | |
166 | #[doc (hidden)] |
167 | pub mod macros; |
168 | |
169 | mod spanned; |
170 | pub use crate::spanned::Spanned; |
171 | |
172 | // Just for rustdoc |
173 | #[allow (unused_imports)] |
174 | use crate::datetime::Datetime; |
175 | #[allow (unused_imports)] |
176 | use core::str::FromStr; |
177 | |