pistonite_cu/parse/toml_impl.rs
1/// `serde` TOML integration via the `toml` crate
2///
3/// Since `serde` derives requires linking with `serde` crate,
4/// you have to add it to your `Cargo.toml`:
5/// ```toml
6/// [dependencies]
7/// serde = "1"
8/// ```
9///
10/// ```rust
11/// # use pistonite_cu as cu;
12/// use cu::pre::*; // with `serde` feature, Serialize and Deserialize are
13/// // part of the prelude
14///
15/// use std::collections::BTreeMap;
16///
17/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
18/// struct FooBar {
19/// foo: BTreeMap<String, String>,
20/// }
21///
22/// # fn main() -> cu::Result<()> {
23/// // the toml macro and toml module will also be part of the prelude
24/// let value1 = toml! {
25/// [foo]
26/// bar = "biz"
27/// };
28/// assert_eq!(value1["foo"]["bar"], "biz".into());
29/// let value2: FooBar = toml::parse(r#"
30/// [foo]
31/// bar = "biz"
32/// "#)?;
33/// assert_eq!(
34/// Some("biz"),
35/// value2.foo.get("bar").map(|x| x.as_str()),
36/// );
37///
38/// # Ok(()) }
39/// ```
40pub mod toml {
41 use crate::{Context, Parse};
42 pub use ::toml::value::{Date, Datetime, Offset, Time};
43 pub use ::toml::{Spanned, Table, Value, value::Array as Vec};
44 #[cfg(feature = "parse-impl")]
45 pub use ::toml::{de, map, ser, value};
46 use serde::{Deserialize, Serialize};
47
48 /// TOML parse delegate. See [`toml`](module@crate::toml)
49 pub struct Toml<T>(std::marker::PhantomData<T>);
50 impl<T: for<'a> Deserialize<'a>> Parse for Toml<T> {
51 type Output = T;
52
53 fn parse_borrowed(x: &str) -> crate::Result<Self::Output> {
54 parse(x)
55 }
56 }
57
58 /// Parse value from a TOML `&str`
59 #[inline(always)]
60 pub fn parse<'a, T: Deserialize<'a>>(x: &'a str) -> crate::Result<T> {
61 ::toml::from_str(x).with_context(|| {
62 format!(
63 "failed to parse input as toml into {}",
64 std::any::type_name::<T>()
65 )
66 })
67 }
68
69 /// Parse value from a reader that yields TOML
70 #[inline(always)]
71 pub fn read<T: for<'a> Deserialize<'a>>(x: impl std::io::Read) -> crate::Result<T> {
72 Toml::<T>::parse_read(x)
73 }
74
75 /// Parse value from an async reader that yields TOML
76 #[cfg(feature = "coroutine")]
77 pub async fn co_read<T: for<'a> Deserialize<'a>>(
78 x: impl tokio::io::AsyncRead + Unpin,
79 ) -> crate::Result<T> {
80 crate::co_read::<Toml<T>>(x).await
81 }
82
83 /// Convert the value to a TOML string
84 pub fn stringify<T: ?Sized + Serialize>(x: &T) -> crate::Result<String> {
85 use crate::Context;
86 crate::check!(
87 toml::to_string(x),
88 "failed to serialize {} to toml",
89 std::any::type_name::<T>()
90 )
91 }
92
93 /// Convert the value to a pretty-formatted TOML string
94 pub fn stringify_pretty<T: ?Sized + Serialize>(x: &T) -> crate::Result<String> {
95 use crate::Context;
96 crate::check!(
97 toml::to_string_pretty(x),
98 "failed to serialize {} to toml",
99 std::any::type_name::<T>()
100 )
101 }
102}
103#[cfg_attr(any(docsrs, feature = "nightly"), doc(cfg(feature = "toml")))]
104pub use ::toml::toml;