toml/de/deserializer/
value.rs1use serde::de::IntoDeserializer as _;
2use serde_spanned::Spanned;
3
4use super::ArrayDeserializer;
5use super::DatetimeDeserializer;
6use super::TableDeserializer;
7use crate::alloc_prelude::*;
8use crate::de::DeString;
9use crate::de::DeTable;
10use crate::de::DeValue;
11use crate::de::Error;
12
13pub struct ValueDeserializer<'i> {
42 span: core::ops::Range<usize>,
43 input: DeValue<'i>,
44 validate_struct_keys: bool,
45}
46
47impl<'i> ValueDeserializer<'i> {
48 pub fn parse(raw: &'i str) -> Result<Self, Error> {
50 let input = DeValue::parse(raw)?;
51 let span = input.span();
52 let input = input.into_inner();
53 Ok(Self::with_parts(input, span))
54 }
55
56 #[deprecated(since = "0.9.0", note = "replaced with `ValueDeserializer::parse`")]
58 pub fn new(raw: &'i str) -> Result<Self, Error> {
59 Self::parse(raw)
60 }
61
62 pub(crate) fn with_parts(input: DeValue<'i>, span: core::ops::Range<usize>) -> Self {
63 Self {
64 input,
65 span,
66 validate_struct_keys: false,
67 }
68 }
69
70 pub(crate) fn with_struct_key_validation(mut self) -> Self {
71 self.validate_struct_keys = true;
72 self
73 }
74}
75
76impl<'i> From<Spanned<DeValue<'i>>> for ValueDeserializer<'i> {
77 fn from(root: Spanned<DeValue<'i>>) -> Self {
78 let span = root.span();
79 let root = root.into_inner();
80 Self::with_parts(root, span)
81 }
82}
83
84impl<'de> serde::Deserializer<'de> for ValueDeserializer<'de> {
85 type Error = Error;
86
87 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
88 where
89 V: serde::de::Visitor<'de>,
90 {
91 let span = self.span.clone();
92 match self.input {
93 DeValue::String(DeString::Owned(v)) => visitor.visit_string(v),
94 DeValue::String(DeString::Borrowed(v)) => visitor.visit_str(v),
95 DeValue::Integer(v) => {
96 if let Some(v) = v.to_i64() {
97 visitor.visit_i64(v)
98 } else if let Some(v) = v.to_u64() {
99 visitor.visit_u64(v)
100 } else if let Some(v) = v.to_i128() {
101 visitor.visit_i128(v)
102 } else if let Some(v) = v.to_u128() {
103 visitor.visit_u128(v)
104 } else {
105 Err(Error::custom("integer number overflowed", None))
106 }
107 }
108 DeValue::Float(v) => {
109 if let Some(v) = v.to_f64() {
110 visitor.visit_f64(v)
111 } else {
112 Err(Error::custom("floating-point number overflowed", None))
113 }
114 }
115 DeValue::Boolean(v) => visitor.visit_bool(v),
116 DeValue::Datetime(v) => visitor.visit_map(DatetimeDeserializer::new(v)),
117 DeValue::Array(v) => ArrayDeserializer::new(v, span.clone()).deserialize_any(visitor),
118 DeValue::Table(v) => TableDeserializer::new(v, span.clone()).deserialize_any(visitor),
119 }
120 .map_err(|mut e: Self::Error| {
121 if e.span().is_none() {
122 e.set_span(Some(span));
123 }
124 e
125 })
126 }
127
128 fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
129 where
130 V: serde::de::Visitor<'de>,
131 {
132 self.deserialize_any(visitor)
133 }
134
135 fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
136 where
137 V: serde::de::Visitor<'de>,
138 {
139 self.deserialize_any(visitor)
140 }
141
142 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
145 where
146 V: serde::de::Visitor<'de>,
147 {
148 let span = self.span.clone();
149 visitor.visit_some(self).map_err(|mut e: Self::Error| {
150 if e.span().is_none() {
151 e.set_span(Some(span));
152 }
153 e
154 })
155 }
156
157 fn deserialize_newtype_struct<V>(
158 self,
159 _name: &'static str,
160 visitor: V,
161 ) -> Result<V::Value, Error>
162 where
163 V: serde::de::Visitor<'de>,
164 {
165 let span = self.span.clone();
166 visitor
167 .visit_newtype_struct(self)
168 .map_err(|mut e: Self::Error| {
169 if e.span().is_none() {
170 e.set_span(Some(span));
171 }
172 e
173 })
174 }
175
176 fn deserialize_struct<V>(
177 self,
178 name: &'static str,
179 fields: &'static [&'static str],
180 visitor: V,
181 ) -> Result<V::Value, Error>
182 where
183 V: serde::de::Visitor<'de>,
184 {
185 if serde_spanned::de::is_spanned(name) {
186 let span = self.span.clone();
187 return visitor.visit_map(super::SpannedDeserializer::new(self, span));
188 }
189
190 if toml_datetime::de::is_datetime(name) {
191 let span = self.span.clone();
192 if let DeValue::Datetime(d) = self.input {
193 return visitor.visit_map(DatetimeDeserializer::new(d)).map_err(
194 |mut e: Self::Error| {
195 if e.span().is_none() {
196 e.set_span(Some(span));
197 }
198 e
199 },
200 );
201 }
202 }
203
204 if self.validate_struct_keys {
205 let span = self.span.clone();
206 match &self.input {
207 DeValue::Table(values) => validate_struct_keys(values, fields),
208 _ => Ok(()),
209 }
210 .map_err(|mut e: Self::Error| {
211 if e.span().is_none() {
212 e.set_span(Some(span));
213 }
214 e
215 })?;
216 }
217
218 self.deserialize_any(visitor)
219 }
220
221 fn deserialize_enum<V>(
223 self,
224 name: &'static str,
225 variants: &'static [&'static str],
226 visitor: V,
227 ) -> Result<V::Value, Error>
228 where
229 V: serde::de::Visitor<'de>,
230 {
231 let span = self.span.clone();
232 match self.input {
233 DeValue::String(v) => visitor.visit_enum(v.into_deserializer()),
234 DeValue::Table(v) => {
235 TableDeserializer::new(v, span.clone()).deserialize_enum(name, variants, visitor)
236 }
237 _ => Err(Error::custom("wanted string or table", Some(span.clone()))),
238 }
239 .map_err(|mut e: Self::Error| {
240 if e.span().is_none() {
241 e.set_span(Some(span));
242 }
243 e
244 })
245 }
246
247 serde::forward_to_deserialize_any! {
248 bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
249 bytes byte_buf map unit
250 ignored_any unit_struct tuple_struct tuple identifier
251 }
252}
253
254impl<'de> serde::de::IntoDeserializer<'de, Error> for ValueDeserializer<'de> {
255 type Deserializer = Self;
256
257 fn into_deserializer(self) -> Self::Deserializer {
258 self
259 }
260}
261
262impl<'de> serde::de::IntoDeserializer<'de, Error> for Spanned<DeValue<'de>> {
263 type Deserializer = ValueDeserializer<'de>;
264
265 fn into_deserializer(self) -> Self::Deserializer {
266 ValueDeserializer::from(self)
267 }
268}
269
270pub(crate) fn validate_struct_keys(
271 table: &DeTable<'_>,
272 fields: &'static [&'static str],
273) -> Result<(), Error> {
274 let extra_fields = table
275 .keys()
276 .filter_map(|key| {
277 if !fields.contains(&key.get_ref().as_ref()) {
278 Some(key.clone())
279 } else {
280 None
281 }
282 })
283 .collect::<Vec<_>>();
284
285 if extra_fields.is_empty() {
286 Ok(())
287 } else {
288 Err(Error::custom(
289 format!(
290 "unexpected keys in table: {}, available keys: {}",
291 extra_fields
292 .iter()
293 .map(|k| k.get_ref().as_ref())
294 .collect::<Vec<_>>()
295 .join(", "),
296 fields.join(", "),
297 ),
298 Some(extra_fields[0].span()),
299 ))
300 }
301}