| use std::fmt; |
| |
| use serde::de; |
| use serde::ser; |
| |
| use crate::map::Map; |
| use crate::Value; |
| |
| /// Type representing a TOML table, payload of the `Value::Table` variant. |
| /// By default it is backed by a BTreeMap, enable the `preserve_order` feature |
| /// to use a LinkedHashMap instead. |
| pub type Table = Map<String, Value>; |
| |
| impl Table { |
| /// Convert a `T` into `toml::Table`. |
| /// |
| /// This conversion can fail if `T`'s implementation of `Serialize` decides to |
| /// fail, or if `T` contains a map with non-string keys. |
| pub fn try_from<T>(value: T) -> Result<Self, crate::ser::Error> |
| where |
| T: ser::Serialize, |
| { |
| value.serialize(crate::value::TableSerializer) |
| } |
| |
| /// Interpret a `toml::Table` as an instance of type `T`. |
| /// |
| /// This conversion can fail if the structure of the `Table` does not match the structure |
| /// expected by `T`, for example if `T` is a bool which can't be mapped to a `Table`. It can |
| /// also fail if the structure is correct but `T`'s implementation of `Deserialize` decides |
| /// that something is wrong with the data, for example required struct fields are missing from |
| /// the TOML map or some number is too big to fit in the expected primitive type. |
| pub fn try_into<'de, T>(self) -> Result<T, crate::de::Error> |
| where |
| T: de::Deserialize<'de>, |
| { |
| de::Deserialize::deserialize(self) |
| } |
| } |
| |
| #[cfg(feature = "display")] |
| impl fmt::Display for Table { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| crate::ser::to_string(self) |
| .expect("Unable to represent value as string") |
| .fmt(f) |
| } |
| } |
| |
| #[cfg(feature = "parse")] |
| impl std::str::FromStr for Table { |
| type Err = crate::de::Error; |
| fn from_str(s: &str) -> Result<Self, Self::Err> { |
| crate::from_str(s) |
| } |
| } |
| |
| impl<'de> de::Deserializer<'de> for Table { |
| type Error = crate::de::Error; |
| |
| fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> |
| where |
| V: de::Visitor<'de>, |
| { |
| Value::Table(self).deserialize_any(visitor) |
| } |
| |
| #[inline] |
| fn deserialize_enum<V>( |
| self, |
| name: &'static str, |
| variants: &'static [&'static str], |
| visitor: V, |
| ) -> Result<V::Value, crate::de::Error> |
| where |
| V: de::Visitor<'de>, |
| { |
| Value::Table(self).deserialize_enum(name, variants, visitor) |
| } |
| |
| // `None` is interpreted as a missing field so be sure to implement `Some` |
| // as a present field. |
| fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> |
| where |
| V: de::Visitor<'de>, |
| { |
| Value::Table(self).deserialize_option(visitor) |
| } |
| |
| fn deserialize_newtype_struct<V>( |
| self, |
| name: &'static str, |
| visitor: V, |
| ) -> Result<V::Value, crate::de::Error> |
| where |
| V: de::Visitor<'de>, |
| { |
| Value::Table(self).deserialize_newtype_struct(name, visitor) |
| } |
| |
| serde::forward_to_deserialize_any! { |
| bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq |
| bytes byte_buf map unit_struct tuple_struct struct |
| tuple ignored_any identifier |
| } |
| } |
| |
| impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Table { |
| type Deserializer = Self; |
| |
| fn into_deserializer(self) -> Self { |
| self |
| } |
| } |