//! Deserializing TOML into Rust structures. //! //! This module contains all the Serde support for deserializing TOML documents //! into Rust structures. Note that some top-level functions here are also //! provided at the top of the crate. /// Deserializes a string into a type. /// /// This function will attempt to interpret `s` as a TOML document and /// deserialize `T` from the document. /// /// To deserializes TOML values, instead of documents, see [`ValueDeserializer`]. /// /// # Examples /// /// ``` /// use serde::Deserialize; /// /// #[derive(Deserialize)] /// struct Config { /// title: String, /// owner: Owner, /// } /// /// #[derive(Deserialize)] /// struct Owner { /// name: String, /// } /// /// let config: Config = toml::from_str(r#" /// title = 'TOML Example' /// /// [owner] /// name = 'Lisa' /// "#).unwrap(); /// /// assert_eq!(config.title, "TOML Example"); /// assert_eq!(config.owner.name, "Lisa"); /// ``` #[cfg(feature = "parse")] pub fn from_str(s: &'_ str) -> Result where T: serde::de::DeserializeOwned, { T::deserialize(Deserializer::new(s)) } /// Errors that can occur when deserializing a type. #[derive(Debug, PartialEq, Eq, Clone)] pub struct Error { inner: crate::edit::de::Error, } impl Error { fn new(inner: crate::edit::de::Error) -> Self { Self { inner } } pub(crate) fn add_key(&mut self, key: String) { self.inner.add_key(key) } /// What went wrong pub fn message(&self) -> &str { self.inner.message() } /// The start/end index into the original document where the error occurred #[cfg(feature = "parse")] pub fn span(&self) -> Option> { self.inner.span() } } impl serde::de::Error for Error { fn custom(msg: T) -> Self where T: std::fmt::Display, { Error::new(crate::edit::de::Error::custom(msg)) } } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.inner.fmt(f) } } impl std::error::Error for Error {} /// Deserialization TOML document /// /// To deserializes TOML values, instead of documents, see [`ValueDeserializer`]. #[cfg(feature = "parse")] pub struct Deserializer<'a> { input: &'a str, } #[cfg(feature = "parse")] impl<'a> Deserializer<'a> { /// Deserialization implementation for TOML. pub fn new(input: &'a str) -> Self { Self { input } } } #[cfg(feature = "parse")] impl<'de, 'a> serde::Deserializer<'de> for Deserializer<'a> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner.deserialize_any(visitor).map_err(Error::new) } // `None` is interpreted as a missing field so be sure to implement `Some` // as a present field. fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner.deserialize_option(visitor).map_err(Error::new) } fn deserialize_newtype_struct( self, name: &'static str, visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_newtype_struct(name, visitor) .map_err(Error::new) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_struct(name, fields, visitor) .map_err(Error::new) } // Called when the type to deserialize is an enum, as opposed to a field in the type. fn deserialize_enum( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_enum(name, variants, visitor) .map_err(Error::new) } serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bytes byte_buf map unit ignored_any unit_struct tuple_struct tuple identifier } } /// Deserialization TOML [value][crate::Value] /// /// # Example /// /// ``` /// use serde::Deserialize; /// /// #[derive(Deserialize)] /// struct Config { /// title: String, /// owner: Owner, /// } /// /// #[derive(Deserialize)] /// struct Owner { /// name: String, /// } /// /// let config = Config::deserialize(toml::de::ValueDeserializer::new( /// r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"# /// )).unwrap(); /// /// assert_eq!(config.title, "TOML Example"); /// assert_eq!(config.owner.name, "Lisa"); /// ``` #[cfg(feature = "parse")] pub struct ValueDeserializer<'a> { input: &'a str, } #[cfg(feature = "parse")] impl<'a> ValueDeserializer<'a> { /// Deserialization implementation for TOML. pub fn new(input: &'a str) -> Self { Self { input } } } #[cfg(feature = "parse")] impl<'de, 'a> serde::Deserializer<'de> for ValueDeserializer<'a> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner.deserialize_any(visitor).map_err(Error::new) } // `None` is interpreted as a missing field so be sure to implement `Some` // as a present field. fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner.deserialize_option(visitor).map_err(Error::new) } fn deserialize_newtype_struct( self, name: &'static str, visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_newtype_struct(name, visitor) .map_err(Error::new) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_struct(name, fields, visitor) .map_err(Error::new) } // Called when the type to deserialize is an enum, as opposed to a field in the type. fn deserialize_enum( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { let inner = self .input .parse::() .map_err(Error::new)?; inner .deserialize_enum(name, variants, visitor) .map_err(Error::new) } serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bytes byte_buf map unit ignored_any unit_struct tuple_struct tuple identifier } }