1use crate::mapping::{DuplicateKey, MappingVisitor};
2use crate::path::{OwnedPath, Path};
3use crate::value::de::borrowed::ValueRefDeserializer;
4use crate::value::tagged::TagStringVisitor;
5use crate::value::TaggedValue;
6use crate::{error, number, spanned, Error, Sequence, Span, Value};
7use serde::de::{
8 self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as _, Expected, MapAccess,
9 SeqAccess, Unexpected, VariantAccess, Visitor,
10};
11use std::fmt;
12
13mod borrowed;
14mod owned;
15
16pub(crate) use borrowed::{MapRefDeserializer, SeqRefDeserializer};
17pub use owned::ValueDeserializer;
18
19pub type TransformedResult =
21 Result<Option<Value>, Box<dyn std::error::Error + 'static + Send + Sync>>;
22
23pub type DuplicateKeyCallback<'d> =
25 &'d mut dyn for<'p, 'v> FnMut(Path<'p>, &'v Value, &'v Value) -> DuplicateKey;
26
27pub type UnusedKeyCallback<'u> = &'u mut dyn for<'p, 'v> FnMut(Path<'p>, &'v Value, &'v Value);
29
30pub type FieldTransformer<'f> = &'f mut dyn for<'v> FnMut(&'v Value) -> TransformedResult;
32
33impl Value {
34 pub fn from_str<F>(s: &str, duplicate_key_callback: F) -> Result<Self, Error>
36 where
37 F: FnMut(Path<'_>, &Self, &Self) -> DuplicateKey,
38 {
39 let de = crate::de::Deserializer::from_str(s);
40 spanned::set_marker(spanned::Marker::start());
41 let res = deserialize(de, duplicate_key_callback);
42 spanned::reset_marker();
43 res
44 }
45
46 pub fn from_reader<R, F>(rdr: R, duplicate_key_callback: F) -> Result<Self, Error>
48 where
49 R: std::io::Read,
50 F: FnMut(Path<'_>, &Self, &Self) -> DuplicateKey,
51 {
52 let de = crate::de::Deserializer::from_reader(rdr);
53 spanned::set_marker(spanned::Marker::start());
54 let res = deserialize(de, duplicate_key_callback);
55 spanned::reset_marker();
56 res
57 }
58
59 pub fn from_slice<F>(s: &[u8], duplicate_key_callback: F) -> Result<Self, Error>
61 where
62 F: FnMut(Path<'_>, &Self, &Self) -> DuplicateKey,
63 {
64 let de = crate::de::Deserializer::from_slice(s);
65 spanned::set_marker(spanned::Marker::start());
66 let res = deserialize(de, duplicate_key_callback);
67 spanned::reset_marker();
68 res
69 }
70
71 pub fn into_typed<'de, T, U, F>(
73 self,
74 mut unused_key_callback: U,
75 mut field_transformer: F,
76 ) -> Result<T, Error>
77 where
78 T: Deserialize<'de>,
79 U: FnMut(Path<'_>, &Value, &Value),
80 F: for<'v> FnMut(&'v Value) -> TransformedResult,
81 {
82 let de = ValueDeserializer::new_with(
83 self,
84 Path::Root,
85 Some(&mut unused_key_callback),
86 Some(&mut field_transformer),
87 );
88
89 T::deserialize(de)
90 }
91
92 pub fn to_typed<'de, T, U, F>(
95 &'de self,
96 mut unused_key_callback: U,
97 mut field_transformer: F,
98 ) -> Result<T, Error>
99 where
100 T: Deserialize<'de>,
101 U: FnMut(Path<'_>, &Value, &Value),
102 F: for<'v> FnMut(&'v Value) -> TransformedResult,
103 {
104 let de = ValueRefDeserializer::new_with(
105 self,
106 Path::Root,
107 Some(&mut unused_key_callback),
108 Some(&mut field_transformer),
109 );
110
111 T::deserialize(de)
112 }
113}
114
115pub(crate) struct ValueVisitor<'d, 'b> {
116 pub callback: DuplicateKeyCallback<'d>,
117 pub path: Path<'b>,
118}
119
120impl<'de> serde::de::Visitor<'de> for ValueVisitor<'_, '_> {
121 type Value = Value;
122
123 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
124 formatter.write_str("any valid YAML value")
125 }
126
127 fn visit_bool<E>(self, b: bool) -> Result<Value, E>
128 where
129 E: serde::de::Error,
130 {
131 Ok(Value::bool(b))
132 }
133
134 fn visit_i64<E>(self, i: i64) -> Result<Value, E>
135 where
136 E: serde::de::Error,
137 {
138 Ok(Value::number(i.into()))
139 }
140
141 fn visit_u64<E>(self, u: u64) -> Result<Value, E>
142 where
143 E: serde::de::Error,
144 {
145 Ok(Value::number(u.into()))
146 }
147
148 fn visit_f64<E>(self, f: f64) -> Result<Value, E>
149 where
150 E: serde::de::Error,
151 {
152 Ok(Value::number(f.into()))
153 }
154
155 fn visit_str<E>(self, s: &str) -> Result<Value, E>
156 where
157 E: serde::de::Error,
158 {
159 Ok(Value::string(s.to_owned()))
160 }
161
162 fn visit_string<E>(self, s: String) -> Result<Value, E>
163 where
164 E: serde::de::Error,
165 {
166 Ok(Value::string(s))
167 }
168
169 fn visit_unit<E>(self) -> Result<Value, E>
170 where
171 E: serde::de::Error,
172 {
173 Ok(Value::null())
174 }
175
176 fn visit_none<E>(self) -> Result<Value, E>
177 where
178 E: serde::de::Error,
179 {
180 Ok(Value::null())
181 }
182
183 fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
184 where
185 D: Deserializer<'de>,
186 {
187 Deserialize::deserialize(deserializer)
188 }
189
190 fn visit_seq<A>(self, data: A) -> Result<Value, A::Error>
191 where
192 A: SeqAccess<'de>,
193 {
194 let de = serde::de::value::SeqAccessDeserializer::new(data);
195 let visitor = SequenceVisitor {
196 callback: &mut *self.callback,
197 path: self.path,
198 };
199 let sequence = de.deserialize_seq(visitor)?;
200 Ok(Value::sequence(sequence))
201 }
202
203 fn visit_map<A>(self, data: A) -> Result<Value, A::Error>
204 where
205 A: MapAccess<'de>,
206 {
207 let de = serde::de::value::MapAccessDeserializer::new(data);
208 let visitor = MappingVisitor {
209 callback: &mut *self.callback,
210 path: self.path,
211 };
212 let mapping = de.deserialize_map(visitor)?;
213 Ok(Value::mapping(mapping))
214 }
215
216 fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
217 where
218 A: EnumAccess<'de>,
219 {
220 let (tag, contents) = data.variant_seed(TagStringVisitor)?;
221 let value = contents.newtype_variant()?;
222 Ok(Value::tagged(TaggedValue { tag, value }))
223 }
224}
225
226impl<'de> DeserializeSeed<'de> for ValueVisitor<'_, '_> {
227 type Value = Value;
228
229 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
230 where
231 D: Deserializer<'de>,
232 {
233 let start = spanned::get_marker();
234 let val = deserializer.deserialize_any(self)?;
235 let span = Span::from(start..spanned::get_marker());
236
237 #[cfg(feature = "filename")]
238 let span = span.maybe_capture_filename();
239
240 Ok(val.with_span(span))
241 }
242}
243
244struct SequenceVisitor<'d, 'b> {
245 pub callback: DuplicateKeyCallback<'d>,
246 pub path: Path<'b>,
247}
248
249impl<'de> serde::de::Visitor<'de> for SequenceVisitor<'_, '_> {
250 type Value = Sequence;
251
252 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
253 formatter.write_str("a sequence")
254 }
255
256 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
257 where
258 A: SeqAccess<'de>,
259 {
260 let mut values = Vec::new();
261 let mut idx = 0;
262 while let Some(value) = seq.next_element_seed(ValueVisitor {
263 callback: &mut *self.callback,
264 path: Path::Seq {
265 parent: &self.path,
266 index: idx,
267 },
268 })? {
269 idx += 1;
270 values.push(value);
271 }
272
273 Ok(values)
274 }
275}
276
277fn deserialize<'de, D, F>(deserializer: D, mut duplicate_key_callback: F) -> Result<Value, D::Error>
278where
279 D: serde::Deserializer<'de>,
280 F: FnMut(Path<'_>, &Value, &Value) -> DuplicateKey,
281{
282 let start = spanned::get_marker();
283 set_is_deserializing_value();
284 let res = deserializer.deserialize_any(ValueVisitor {
285 callback: &mut duplicate_key_callback,
286 path: Path::Root,
287 });
288 let maybe_state = unsafe { load_deserializer_state() };
289 reset_is_deserializing_value();
290
291 if let Some(state) = maybe_state {
294 return Ok(state.value);
295 }
296
297 let val = res?;
298 let span = Span::from(start..spanned::get_marker());
299
300 #[cfg(feature = "filename")]
301 let span = span.maybe_capture_filename();
302
303 Ok(val.with_span(span))
304}
305
306impl<'de> Deserialize<'de> for Value {
307 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
308 where
309 D: Deserializer<'de>,
310 {
311 deserialize(deserializer, |_, _, _| DuplicateKey::Error)
312 }
313}
314
315macro_rules! maybe_why_not {
316 ($value_ref:expr, $res:expr) => {{
317 let is_expecting_should_be = $crate::shouldbe::is_expecting_should_be_then_reset();
318 let res = $res;
319 match res {
320 Err(err) if is_expecting_should_be => {
321 let msg = err.to_string();
322 $crate::shouldbe::set_why_not($value_ref.clone(), err);
323 Err(Error::custom(msg))
326 }
327 _ => res,
328 }
329 }};
330}
331pub(crate) use maybe_why_not;
332
333impl Value {
334 fn deserialize_number<'de, V>(&self, visitor: V) -> Result<V::Value, Error>
335 where
336 V: Visitor<'de>,
337 {
338 let span = self.span().clone();
339 self.broadcast_end_mark();
340 maybe_why_not!(
341 self,
342 match self.untag_ref() {
343 Value::Number(n, ..) => n.deserialize_any(visitor),
344 other => Err(other.invalid_type(&visitor)),
345 }
346 .map_err(|e| error::set_span(e, span))
347 )
348 }
349
350 #[cold]
351 fn invalid_type(&self, exp: &dyn Expected) -> Error {
352 error::set_span(
353 de::Error::invalid_type(self.unexpected(), exp),
354 self.span().clone(),
355 )
356 }
357
358 #[cold]
360 pub fn unexpected(&self) -> Unexpected<'_> {
361 match self {
362 Value::Null(..) => Unexpected::Unit,
363 Value::Bool(b, ..) => Unexpected::Bool(*b),
364 Value::Number(n, ..) => number::unexpected(n),
365 Value::String(s, ..) => Unexpected::Str(s),
366 Value::Sequence(..) => Unexpected::Seq,
367 Value::Mapping(..) => Unexpected::Map,
368 Value::Tagged(..) => Unexpected::Enum,
369 }
370 }
371}
372
373#[inline]
374fn should_short_circuit_any(has_transformer: bool) -> bool {
375 if !is_deserializing_value_then_reset() {
376 return false;
377 }
378
379 !has_transformer || !crate::verbatim::should_transform_any()
381}
382
383#[inline]
384fn is_deserializing_value_then_reset() -> bool {
385 clear_deserializer_state();
386 private::IS_DESERIALIZING_VALUE.with(|cell| cell.replace(false))
387}
388
389#[inline]
390fn set_is_deserializing_value() {
391 clear_deserializer_state();
392 private::IS_DESERIALIZING_VALUE.with(|cell| cell.set(true));
393}
394
395#[inline]
396fn reset_is_deserializing_value() {
397 clear_deserializer_state();
398 private::IS_DESERIALIZING_VALUE.with(|cell| cell.set(false));
399}
400
401#[inline]
402fn clear_deserializer_state() {
403 private::THE_VALUE.with(|cell| cell.set(None));
404 private::THE_PATH.with(|cell| cell.set(None));
405 private::UNUSED_KEY_CALLBACK.with(|cell| cell.set(None));
406 private::FIELD_TRANSFORMER.with(|cell| cell.set(None));
407}
408
409unsafe fn save_deserializer_state<'u, 'f>(
410 value: Option<Value>,
411 path: Path<'_>,
412 unused_key_callback: Option<UnusedKeyCallback<'u>>,
413 field_transformer: Option<FieldTransformer<'f>>,
414) {
415 private::THE_VALUE.with(|cell| cell.set(value));
416 private::THE_PATH.with(|cell| cell.set(Some(path.to_owned_path())));
417 private::UNUSED_KEY_CALLBACK.with(|cell| {
418 cell.set(unsafe {
419 std::mem::transmute::<Option<UnusedKeyCallback<'u>>, Option<UnusedKeyCallback<'static>>>(unused_key_callback)
420 })
421 });
422 private::FIELD_TRANSFORMER.with(|cell| {
423 cell.set(unsafe {
424 std::mem::transmute::<Option<FieldTransformer<'f>>, Option<FieldTransformer<'static>>>(
425 field_transformer,
426 )
427 })
428 });
429}
430
431pub fn extract_reusable_deserializer_state<'de, D>(
435 deserializer: D,
436) -> Result<DeserializerState, D::Error>
437where
438 D: Deserializer<'de>,
439{
440 set_is_deserializing_value();
441 let _g = crate::verbatim::with_should_not_transform_any();
443 let res = deserializer.deserialize_any(ValueVisitor {
444 callback: &mut |_, _, _| DuplicateKey::Error,
445 path: Path::Root,
446 });
447 let maybe_state = unsafe { load_deserializer_state() };
448 reset_is_deserializing_value();
449
450 if let Some(state) = maybe_state {
451 Ok(state)
452 } else {
453 let val = res?;
454 Ok(DeserializerState::new(val, OwnedPath::Root, None, None))
455 }
456}
457
458pub fn extract_tag_and_deserializer_state<'de, D>(
461 deserializer: D,
462 tag_key: &str,
463) -> Result<(Value, DeserializerState), D::Error>
464where
465 D: Deserializer<'de>,
466{
467 let mut state = extract_reusable_deserializer_state(deserializer)?;
468 let val = &mut state.value;
469 match val {
470 Value::Mapping(map, ..) => {
471 let Some(mut tag) = map.remove(tag_key) else {
472 return Err(D::Error::custom(format!(
473 "Expected tag key {tag_key:?} not found"
474 )));
475 };
476 if let Some(transformer) = &mut state.field_transformer {
477 if let Some(transformed) = transformer(&tag)
478 .map_err(|e| D::Error::custom(format!("Failed to transform tag: {e}")))?
479 {
480 tag = transformed;
481 }
482 }
483
484 Ok((tag, state))
485 }
486 _ => Err(D::Error::custom("Expected a mapping")),
487 }
488}
489
490pub struct DeserializerState {
492 value: Value,
493 path: OwnedPath,
494 unused_key_callback: Option<UnusedKeyCallback<'static>>,
495 field_transformer: Option<FieldTransformer<'static>>,
496}
497
498impl DeserializerState {
499 pub fn new(
501 value: Value,
502 path: OwnedPath,
503 unused_key_callback: Option<UnusedKeyCallback<'static>>,
504 field_transformer: Option<FieldTransformer<'static>>,
505 ) -> Self {
506 Self {
507 value,
508 path,
509 unused_key_callback,
510 field_transformer,
511 }
512 }
513
514 pub fn get_deserializer<'de, 'u>(
516 &'de mut self,
517 unused_key_callback: Option<UnusedKeyCallback<'u>>,
518 ) -> ValueRefDeserializer<'de, 'de, 'u, 'de> {
519 let field_transformer = self
520 .field_transformer
521 .as_deref_mut()
522 .map(|cb| &mut *cb as FieldTransformer<'_>);
523
524 ValueRefDeserializer::new_with(
525 &self.value,
526 *self.path.as_path(),
527 unused_key_callback,
528 field_transformer,
529 )
530 }
531
532 pub fn get_owned_deserializer<'de>(&'de mut self) -> ValueDeserializer<'de, 'de, 'de> {
534 let value = std::mem::take(&mut self.value);
535
536 ValueDeserializer::new_with(
537 value,
538 *self.path.as_path(),
539 self.unused_key_callback
540 .as_deref_mut()
541 .map(|cb| &mut *cb as UnusedKeyCallback<'_>),
542 self.field_transformer
543 .as_deref_mut()
544 .map(|cb| &mut *cb as FieldTransformer<'_>),
545 )
546 }
547
548 pub fn take_unused_key_callback(&mut self) -> Option<UnusedKeyCallback<'static>> {
550 self.unused_key_callback.take()
551 }
552}
553
554unsafe fn load_deserializer_state() -> Option<DeserializerState> {
555 let Some(value) = private::THE_VALUE.with(|cell| cell.take()) else {
556 return None;
557 };
558
559 let path = private::THE_PATH
560 .with(|cell| cell.take())
561 .unwrap_or(OwnedPath::Root);
562 let unused_key_callback = private::UNUSED_KEY_CALLBACK.with(|cell| cell.take());
563 let field_transformer = private::FIELD_TRANSFORMER.with(|cell| cell.take());
564
565 Some(DeserializerState {
566 value,
567 path,
568 unused_key_callback,
569 field_transformer,
570 })
571}
572
573mod private {
574 use crate::{path::OwnedPath, Value};
575
576 thread_local! {
577 pub static IS_DESERIALIZING_VALUE: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
578
579 pub static THE_VALUE: std::cell::Cell<Option<Value>> = const { std::cell::Cell::new(None) };
580 pub static THE_PATH: std::cell::Cell<Option<OwnedPath>> = const { std::cell::Cell::new(None) };
581 pub static UNUSED_KEY_CALLBACK: std::cell::Cell<Option<super::UnusedKeyCallback<'static>>> = std::cell::Cell::new(
582 None
583 );
584 pub static FIELD_TRANSFORMER: std::cell::Cell<Option<super::FieldTransformer<'static>>> = std::cell::Cell::new(
585 None
586 );
587 }
588}