1 use serde::de::IntoDeserializer as _; 2 3 use crate::de::DatetimeDeserializer; 4 use crate::de::Error; 5 6 /// Deserialization implementation for TOML [values][crate::Value]. 7 /// 8 /// Can be created either directly from TOML strings, using [`std::str::FromStr`], 9 /// or from parsed [values][crate::Value] using [`serde::de::IntoDeserializer::into_deserializer`]. 10 /// 11 /// # Example 12 /// 13 /// ``` 14 /// # #[cfg(feature = "parse")] { 15 /// # #[cfg(feature = "display")] { 16 /// use serde::Deserialize; 17 /// 18 /// #[derive(Deserialize)] 19 /// struct Config { 20 /// title: String, 21 /// owner: Owner, 22 /// } 23 /// 24 /// #[derive(Deserialize)] 25 /// struct Owner { 26 /// name: String, 27 /// } 28 /// 29 /// let value = r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#; 30 /// let deserializer = value.parse::<toml_edit::de::ValueDeserializer>().unwrap(); 31 /// let config = Config::deserialize(deserializer).unwrap(); 32 /// assert_eq!(config.title, "TOML Example"); 33 /// assert_eq!(config.owner.name, "Lisa"); 34 /// # } 35 /// # } 36 /// ``` 37 pub struct ValueDeserializer { 38 input: crate::Item, 39 validate_struct_keys: bool, 40 } 41 42 impl ValueDeserializer { new(input: crate::Item) -> Self43 pub(crate) fn new(input: crate::Item) -> Self { 44 Self { 45 input, 46 validate_struct_keys: false, 47 } 48 } 49 with_struct_key_validation(mut self) -> Self50 pub(crate) fn with_struct_key_validation(mut self) -> Self { 51 self.validate_struct_keys = true; 52 self 53 } 54 } 55 56 // Note: this is wrapped by `toml::de::ValueDeserializer` and any trait methods 57 // implemented here need to be wrapped there 58 impl<'de> serde::Deserializer<'de> for ValueDeserializer { 59 type Error = Error; 60 deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: serde::de::Visitor<'de>,61 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 62 where 63 V: serde::de::Visitor<'de>, 64 { 65 let span = self.input.span(); 66 match self.input { 67 crate::Item::None => visitor.visit_none(), 68 crate::Item::Value(crate::Value::String(v)) => visitor.visit_string(v.into_value()), 69 crate::Item::Value(crate::Value::Integer(v)) => visitor.visit_i64(v.into_value()), 70 crate::Item::Value(crate::Value::Float(v)) => visitor.visit_f64(v.into_value()), 71 crate::Item::Value(crate::Value::Boolean(v)) => visitor.visit_bool(v.into_value()), 72 crate::Item::Value(crate::Value::Datetime(v)) => { 73 visitor.visit_map(DatetimeDeserializer::new(v.into_value())) 74 } 75 crate::Item::Value(crate::Value::Array(v)) => { 76 v.into_deserializer().deserialize_any(visitor) 77 } 78 crate::Item::Value(crate::Value::InlineTable(v)) => { 79 v.into_deserializer().deserialize_any(visitor) 80 } 81 crate::Item::Table(v) => v.into_deserializer().deserialize_any(visitor), 82 crate::Item::ArrayOfTables(v) => v.into_deserializer().deserialize_any(visitor), 83 } 84 .map_err(|mut e: Self::Error| { 85 if e.span().is_none() { 86 e.set_span(span); 87 } 88 e 89 }) 90 } 91 92 // `None` is interpreted as a missing field so be sure to implement `Some` 93 // as a present field. deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,94 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> 95 where 96 V: serde::de::Visitor<'de>, 97 { 98 let span = self.input.span(); 99 visitor.visit_some(self).map_err(|mut e: Self::Error| { 100 if e.span().is_none() { 101 e.set_span(span); 102 } 103 e 104 }) 105 } 106 deserialize_newtype_struct<V>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,107 fn deserialize_newtype_struct<V>( 108 self, 109 _name: &'static str, 110 visitor: V, 111 ) -> Result<V::Value, Error> 112 where 113 V: serde::de::Visitor<'de>, 114 { 115 let span = self.input.span(); 116 visitor 117 .visit_newtype_struct(self) 118 .map_err(|mut e: Self::Error| { 119 if e.span().is_none() { 120 e.set_span(span); 121 } 122 e 123 }) 124 } 125 deserialize_struct<V>( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,126 fn deserialize_struct<V>( 127 self, 128 name: &'static str, 129 fields: &'static [&'static str], 130 visitor: V, 131 ) -> Result<V::Value, Error> 132 where 133 V: serde::de::Visitor<'de>, 134 { 135 if serde_spanned::__unstable::is_spanned(name, fields) { 136 if let Some(span) = self.input.span() { 137 return visitor.visit_map(super::SpannedDeserializer::new(self, span)); 138 } 139 } 140 141 if name == toml_datetime::__unstable::NAME && fields == [toml_datetime::__unstable::FIELD] { 142 let span = self.input.span(); 143 if let crate::Item::Value(crate::Value::Datetime(d)) = self.input { 144 return visitor 145 .visit_map(DatetimeDeserializer::new(d.into_value())) 146 .map_err(|mut e: Self::Error| { 147 if e.span().is_none() { 148 e.set_span(span); 149 } 150 e 151 }); 152 } 153 } 154 155 if self.validate_struct_keys { 156 let span = self.input.span(); 157 match &self.input { 158 crate::Item::Table(values) => super::validate_struct_keys(&values.items, fields), 159 crate::Item::Value(crate::Value::InlineTable(values)) => { 160 super::validate_struct_keys(&values.items, fields) 161 } 162 _ => Ok(()), 163 } 164 .map_err(|mut e: Self::Error| { 165 if e.span().is_none() { 166 e.set_span(span); 167 } 168 e 169 })?; 170 } 171 172 self.deserialize_any(visitor) 173 } 174 175 // Called when the type to deserialize is an enum, as opposed to a field in the type. deserialize_enum<V>( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, Error> where V: serde::de::Visitor<'de>,176 fn deserialize_enum<V>( 177 self, 178 name: &'static str, 179 variants: &'static [&'static str], 180 visitor: V, 181 ) -> Result<V::Value, Error> 182 where 183 V: serde::de::Visitor<'de>, 184 { 185 let span = self.input.span(); 186 match self.input { 187 crate::Item::Value(crate::Value::String(v)) => { 188 visitor.visit_enum(v.into_value().into_deserializer()) 189 } 190 crate::Item::Value(crate::Value::InlineTable(v)) => { 191 if v.is_empty() { 192 Err(Error::custom( 193 "wanted exactly 1 element, found 0 elements", 194 v.span(), 195 )) 196 } else if v.len() != 1 { 197 Err(Error::custom( 198 "wanted exactly 1 element, more than 1 element", 199 v.span(), 200 )) 201 } else { 202 v.into_deserializer() 203 .deserialize_enum(name, variants, visitor) 204 } 205 } 206 crate::Item::Table(v) => v 207 .into_deserializer() 208 .deserialize_enum(name, variants, visitor), 209 e => Err(Error::custom("wanted string or table", e.span())), 210 } 211 .map_err(|mut e: Self::Error| { 212 if e.span().is_none() { 213 e.set_span(span); 214 } 215 e 216 }) 217 } 218 219 serde::forward_to_deserialize_any! { 220 bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq 221 bytes byte_buf map unit 222 ignored_any unit_struct tuple_struct tuple identifier 223 } 224 } 225 226 impl<'de> serde::de::IntoDeserializer<'de, Error> for ValueDeserializer { 227 type Deserializer = Self; 228 into_deserializer(self) -> Self::Deserializer229 fn into_deserializer(self) -> Self::Deserializer { 230 self 231 } 232 } 233 234 impl<'de> serde::de::IntoDeserializer<'de, Error> for crate::Value { 235 type Deserializer = ValueDeserializer; 236 into_deserializer(self) -> Self::Deserializer237 fn into_deserializer(self) -> Self::Deserializer { 238 ValueDeserializer::new(crate::Item::Value(self)) 239 } 240 } 241 242 impl crate::Item { into_deserializer(self) -> ValueDeserializer243 pub(crate) fn into_deserializer(self) -> ValueDeserializer { 244 ValueDeserializer::new(self) 245 } 246 } 247 248 #[cfg(feature = "parse")] 249 impl std::str::FromStr for ValueDeserializer { 250 type Err = Error; 251 252 /// Parses a value from a &str from_str(s: &str) -> Result<Self, Self::Err>253 fn from_str(s: &str) -> Result<Self, Self::Err> { 254 let v = crate::parser::parse_value(s).map_err(Error::from)?; 255 Ok(v.into_deserializer()) 256 } 257 } 258