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