Skip to main content

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;