serde_brief/value/
de.rs

1//! Deserialization from [Value] to any type.
2#![cfg_attr(
3	feature = "tracing",
4	allow(clippy::used_underscore_binding, reason = "Only used in tracing::instrument")
5)]
6
7use ::serde::de::{Error, IntoDeserializer, Unexpected};
8
9use super::*;
10
11/// Deserializer to deserialize a [Value] into any type.
12#[derive(Debug)]
13pub struct ValueDeserializer<'de>(Value<'de>);
14
15impl<'de> ValueDeserializer<'de> {
16	/// Create a new deserializer from the given value.
17	#[must_use]
18	pub const fn new(value: Value<'de>) -> Self {
19		Self(value)
20	}
21
22	/// Deserialize the value.
23	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
24	fn deserialize<V>(self, visitor: V) -> Result<V::Value>
25	where
26		V: ::serde::de::Visitor<'de>,
27	{
28		match self.0 {
29			Value::Null => visitor.visit_none(),
30			Value::Bool(b) => visitor.visit_bool(b),
31			Value::Integer(int) => visit_integer(int, visitor),
32			Value::Float(Float::F32(float)) => visitor.visit_f32(float),
33			Value::Float(Float::F64(float)) => visitor.visit_f64(float),
34			Value::Bytes(Cow::Borrowed(bytes)) => visitor.visit_borrowed_bytes(bytes),
35			Value::Bytes(Cow::Owned(bytes)) => visitor.visit_byte_buf(bytes),
36			Value::String(Cow::Borrowed(s)) => visitor.visit_borrowed_str(s),
37			Value::String(Cow::Owned(s)) => visitor.visit_string(s),
38			Value::Array(arr) => visitor.visit_seq(ValueSeqDeserializer(arr)),
39			Value::Map(map) => visitor.visit_map(ValueMapDeserializer(map)),
40		}
41	}
42}
43
44impl<'de> ::serde::de::Deserializer<'de> for ValueDeserializer<'de> {
45	type Error = crate::Error;
46
47	#[inline]
48	fn is_human_readable(&self) -> bool {
49		true
50	}
51
52	#[inline]
53	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
54	fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
55	where
56		V: serde::de::Visitor<'de>,
57	{
58		Self::deserialize(self, visitor)
59	}
60
61	#[inline]
62	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
63	fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
64	where
65		V: serde::de::Visitor<'de>,
66	{
67		match self.0 {
68			Value::Bool(value) => visitor.visit_bool(value),
69			other => Err(Error::invalid_type(Unexpected::from(&other), &"bool")),
70		}
71	}
72
73	#[inline]
74	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
75	fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
76	where
77		V: serde::de::Visitor<'de>,
78	{
79		match self.0 {
80			Value::Integer(int) => visit_integer(int, visitor),
81			other => Err(Error::invalid_type(Unexpected::from(&other), &"i8")),
82		}
83	}
84
85	#[inline]
86	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
87	fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
88	where
89		V: serde::de::Visitor<'de>,
90	{
91		match self.0 {
92			Value::Integer(int) => visit_integer(int, visitor),
93			other => Err(Error::invalid_type(Unexpected::from(&other), &"i16")),
94		}
95	}
96
97	#[inline]
98	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
99	fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
100	where
101		V: serde::de::Visitor<'de>,
102	{
103		match self.0 {
104			Value::Integer(int) => visit_integer(int, visitor),
105			other => Err(Error::invalid_type(Unexpected::from(&other), &"i32")),
106		}
107	}
108
109	#[inline]
110	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
111	fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
112	where
113		V: serde::de::Visitor<'de>,
114	{
115		match self.0 {
116			Value::Integer(int) => visit_integer(int, visitor),
117			other => Err(Error::invalid_type(Unexpected::from(&other), &"i64")),
118		}
119	}
120
121	#[inline]
122	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
123	fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
124	where
125		V: serde::de::Visitor<'de>,
126	{
127		match self.0 {
128			Value::Integer(int) => visit_integer(int, visitor),
129			other => Err(Error::invalid_type(Unexpected::from(&other), &"u8")),
130		}
131	}
132
133	#[inline]
134	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
135	fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
136	where
137		V: serde::de::Visitor<'de>,
138	{
139		match self.0 {
140			Value::Integer(int) => visit_integer(int, visitor),
141			other => Err(Error::invalid_type(Unexpected::from(&other), &"u16")),
142		}
143	}
144
145	#[inline]
146	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
147	fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
148	where
149		V: serde::de::Visitor<'de>,
150	{
151		match self.0 {
152			Value::Integer(int) => visit_integer(int, visitor),
153			other => Err(Error::invalid_type(Unexpected::from(&other), &"u32")),
154		}
155	}
156
157	#[inline]
158	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
159	fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
160	where
161		V: serde::de::Visitor<'de>,
162	{
163		match self.0 {
164			Value::Integer(int) => visit_integer(int, visitor),
165			other => Err(Error::invalid_type(Unexpected::from(&other), &"u64")),
166		}
167	}
168
169	#[inline]
170	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
171	fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
172	where
173		V: serde::de::Visitor<'de>,
174	{
175		match self.0 {
176			Value::Integer(int) => visit_integer(int, visitor),
177			other => Err(Error::invalid_type(Unexpected::from(&other), &"i128")),
178		}
179	}
180
181	#[inline]
182	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
183	fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
184	where
185		V: serde::de::Visitor<'de>,
186	{
187		match self.0 {
188			Value::Integer(int) => visit_integer(int, visitor),
189			other => Err(Error::invalid_type(Unexpected::from(&other), &"u128")),
190		}
191	}
192
193	#[inline]
194	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
195	fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
196	where
197		V: serde::de::Visitor<'de>,
198	{
199		match self.0 {
200			Value::Float(Float::F32(float)) => visitor.visit_f32(float),
201			Value::Float(Float::F64(float)) => visitor.visit_f64(float),
202			other => Err(Error::invalid_type(Unexpected::from(&other), &"float")),
203		}
204	}
205
206	#[inline]
207	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
208	fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
209	where
210		V: serde::de::Visitor<'de>,
211	{
212		match self.0 {
213			Value::Float(Float::F32(float)) => visitor.visit_f32(float),
214			Value::Float(Float::F64(float)) => visitor.visit_f64(float),
215			other => Err(Error::invalid_type(Unexpected::from(&other), &"float")),
216		}
217	}
218
219	#[inline]
220	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
221	fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
222	where
223		V: serde::de::Visitor<'de>,
224	{
225		match self.0 {
226			Value::String(Cow::Borrowed(s)) => visitor.visit_borrowed_str(s),
227			Value::String(Cow::Owned(s)) => visitor.visit_string(s),
228			other => Err(Error::invalid_type(Unexpected::from(&other), &"char")),
229		}
230	}
231
232	#[inline]
233	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
234	fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
235	where
236		V: serde::de::Visitor<'de>,
237	{
238		match self.0 {
239			Value::String(Cow::Borrowed(s)) => visitor.visit_borrowed_str(s),
240			Value::String(Cow::Owned(s)) => visitor.visit_string(s),
241			other => Err(Error::invalid_type(Unexpected::from(&other), &"string")),
242		}
243	}
244
245	#[inline]
246	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
247	fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
248	where
249		V: serde::de::Visitor<'de>,
250	{
251		match self.0 {
252			Value::String(Cow::Borrowed(s)) => visitor.visit_borrowed_str(s),
253			Value::String(Cow::Owned(s)) => visitor.visit_string(s),
254			other => Err(Error::invalid_type(Unexpected::from(&other), &"string")),
255		}
256	}
257
258	#[inline]
259	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
260	fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
261	where
262		V: serde::de::Visitor<'de>,
263	{
264		match self.0 {
265			Value::Bytes(Cow::Borrowed(bytes)) => visitor.visit_borrowed_bytes(bytes),
266			Value::Bytes(Cow::Owned(bytes)) => visitor.visit_byte_buf(bytes),
267			other => Err(Error::invalid_type(Unexpected::from(&other), &"bytes")),
268		}
269	}
270
271	#[inline]
272	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
273	fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
274	where
275		V: serde::de::Visitor<'de>,
276	{
277		match self.0 {
278			Value::Bytes(Cow::Borrowed(bytes)) => visitor.visit_borrowed_bytes(bytes),
279			Value::Bytes(Cow::Owned(bytes)) => visitor.visit_byte_buf(bytes),
280			other => Err(Error::invalid_type(Unexpected::from(&other), &"bytes")),
281		}
282	}
283
284	#[inline]
285	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
286	fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
287	where
288		V: serde::de::Visitor<'de>,
289	{
290		if matches!(&self.0, Value::Null) { visitor.visit_none() } else { visitor.visit_some(self) }
291	}
292
293	#[inline]
294	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
295	fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
296	where
297		V: serde::de::Visitor<'de>,
298	{
299		match self.0 {
300			Value::Null => visitor.visit_unit(),
301			other => Err(Error::invalid_type(Unexpected::from(&other), &"unit")),
302		}
303	}
304
305	#[inline]
306	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
307	fn deserialize_unit_struct<V>(
308		self,
309		_name: &'static str,
310		visitor: V,
311	) -> Result<V::Value, Self::Error>
312	where
313		V: serde::de::Visitor<'de>,
314	{
315		match self.0 {
316			Value::Null => visitor.visit_unit(),
317			other => Err(Error::invalid_type(Unexpected::from(&other), &"unit")),
318		}
319	}
320
321	#[inline]
322	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
323	fn deserialize_newtype_struct<V>(
324		self,
325		_name: &'static str,
326		visitor: V,
327	) -> Result<V::Value, Self::Error>
328	where
329		V: serde::de::Visitor<'de>,
330	{
331		visitor.visit_newtype_struct(self)
332	}
333
334	#[inline]
335	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
336	fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
337	where
338		V: serde::de::Visitor<'de>,
339	{
340		match self.0 {
341			Value::Array(arr) => visitor.visit_seq(ValueSeqDeserializer(arr)),
342			other => Err(Error::invalid_type(Unexpected::from(&other), &"sequence")),
343		}
344	}
345
346	#[inline]
347	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
348	fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
349	where
350		V: serde::de::Visitor<'de>,
351	{
352		match self.0 {
353			Value::Array(arr) => visitor.visit_seq(ValueSeqDeserializer(arr)),
354			other => Err(Error::invalid_type(Unexpected::from(&other), &"tuple")),
355		}
356	}
357
358	#[inline]
359	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
360	fn deserialize_tuple_struct<V>(
361		self,
362		_name: &'static str,
363		_len: usize,
364		visitor: V,
365	) -> Result<V::Value, Self::Error>
366	where
367		V: serde::de::Visitor<'de>,
368	{
369		match self.0 {
370			Value::Array(arr) => visitor.visit_seq(ValueSeqDeserializer(arr)),
371			other => Err(Error::invalid_type(Unexpected::from(&other), &"tuple struct")),
372		}
373	}
374
375	#[inline]
376	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
377	fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
378	where
379		V: serde::de::Visitor<'de>,
380	{
381		match self.0 {
382			Value::Map(map) => visitor.visit_map(ValueMapDeserializer(map)),
383			other => Err(Error::invalid_type(Unexpected::from(&other), &"map")),
384		}
385	}
386
387	#[inline]
388	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
389	fn deserialize_struct<V>(
390		self,
391		_name: &'static str,
392		_fields: &'static [&'static str],
393		visitor: V,
394	) -> Result<V::Value, Self::Error>
395	where
396		V: serde::de::Visitor<'de>,
397	{
398		match self.0 {
399			Value::Map(map) => visitor.visit_map(ValueMapDeserializer(map)),
400			other => Err(Error::invalid_type(Unexpected::from(&other), &"map")),
401		}
402	}
403
404	#[inline]
405	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
406	fn deserialize_enum<V>(
407		self,
408		_name: &'static str,
409		_variants: &'static [&'static str],
410		visitor: V,
411	) -> Result<V::Value, Self::Error>
412	where
413		V: serde::de::Visitor<'de>,
414	{
415		match self.0 {
416			Value::Integer(Integer::Unsigned(int)) =>
417			{
418				#[expect(clippy::cast_possible_truncation, reason = "Enum discriminators are i32")]
419				visitor.visit_enum((int as u32).into_deserializer())
420			}
421			Value::String(s) => visitor.visit_enum(s.as_ref().into_deserializer()),
422			Value::Map(map) => visitor.visit_enum(ValueEnumDeserializer(map)),
423			other => Err(Error::invalid_type(Unexpected::from(&other), &"enum")),
424		}
425	}
426
427	#[inline]
428	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
429	fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
430	where
431		V: serde::de::Visitor<'de>,
432	{
433		match self.0 {
434			Value::Integer(Integer::Unsigned(_)) => self.deserialize_u32(visitor),
435			Value::String(_) => self.deserialize_str(visitor),
436			other => Err(Error::invalid_type(Unexpected::from(&other), &"identifier")),
437		}
438	}
439
440	#[inline]
441	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
442	fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
443	where
444		V: serde::de::Visitor<'de>,
445	{
446		self.deserialize_any(visitor)
447	}
448}
449
450/// Enum deserializer.
451#[derive(Debug)]
452struct ValueEnumDeserializer<'de>(VecDeque<(Value<'de>, Value<'de>)>);
453
454impl<'de> ::serde::de::EnumAccess<'de> for ValueEnumDeserializer<'de> {
455	type Error = crate::Error;
456	type Variant = ValueDeserializer<'de>;
457
458	#[inline]
459	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
460	fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
461	where
462		V: serde::de::DeserializeSeed<'de>,
463	{
464		if self.0.len() != 1 {
465			return Err(Error::invalid_length(1, &"exactly one key-value-pair"));
466		}
467
468		#[expect(clippy::unwrap_used, reason = "Was just checked")]
469		let (key, value) = self.0.pop_front().unwrap();
470		let res = seed.deserialize(ValueDeserializer(key))?;
471		Ok((res, ValueDeserializer(value)))
472	}
473}
474
475impl<'de> ::serde::de::VariantAccess<'de> for ValueDeserializer<'de> {
476	type Error = crate::Error;
477
478	#[inline]
479	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
480	fn unit_variant(self) -> Result<(), Self::Error> {
481		Err(Error::invalid_type(Unexpected::from(&self.0), &"unit variant"))
482	}
483
484	#[inline]
485	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
486	fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
487	where
488		T: serde::de::DeserializeSeed<'de>,
489	{
490		seed.deserialize(self)
491	}
492
493	#[inline]
494	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
495	fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
496	where
497		V: serde::de::Visitor<'de>,
498	{
499		::serde::de::Deserializer::deserialize_seq(self, visitor)
500	}
501
502	#[inline]
503	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(self, visitor)))]
504	fn struct_variant<V>(
505		self,
506		_fields: &'static [&'static str],
507		visitor: V,
508	) -> Result<V::Value, Self::Error>
509	where
510		V: serde::de::Visitor<'de>,
511	{
512		::serde::de::Deserializer::deserialize_map(self, visitor)
513	}
514}
515
516/// Sequence deserializer.
517#[derive(Debug)]
518struct ValueSeqDeserializer<'de>(VecDeque<Value<'de>>);
519
520impl<'de> ::serde::de::SeqAccess<'de> for ValueSeqDeserializer<'de> {
521	type Error = crate::Error;
522
523	#[inline]
524	fn size_hint(&self) -> Option<usize> {
525		Some(self.0.len())
526	}
527
528	#[inline]
529	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
530	fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
531	where
532		T: serde::de::DeserializeSeed<'de>,
533	{
534		if let Some(value) = self.0.pop_front() {
535			seed.deserialize(ValueDeserializer(value)).map(Some)
536		} else {
537			Ok(None)
538		}
539	}
540}
541
542/// Map deserializer.
543#[derive(Debug)]
544struct ValueMapDeserializer<'de>(VecDeque<(Value<'de>, Value<'de>)>);
545
546impl<'de> ::serde::de::MapAccess<'de> for ValueMapDeserializer<'de> {
547	type Error = crate::Error;
548
549	#[inline]
550	fn size_hint(&self) -> Option<usize> {
551		Some(self.0.len())
552	}
553
554	#[inline]
555	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
556	fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
557	where
558		K: serde::de::DeserializeSeed<'de>,
559	{
560		if let Some((key, _value)) = self.0.front_mut() {
561			let value = ::core::mem::replace(key, Value::Null);
562			Ok(Some(seed.deserialize(ValueDeserializer(value))?))
563		} else {
564			Ok(None)
565		}
566	}
567
568	#[inline]
569	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
570	fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
571	where
572		V: serde::de::DeserializeSeed<'de>,
573	{
574		if let Some((_key, value)) = self.0.pop_front() {
575			Ok(seed.deserialize(ValueDeserializer(value))?)
576		} else {
577			Err(Error::custom("next_value_seed called without next_key_seed"))
578		}
579	}
580
581	#[inline]
582	#[cfg_attr(feature = "tracing", ::tracing::instrument(skip_all))]
583	#[allow(clippy::type_complexity, reason = "Tracing makes this trigger, also it's serde trait")]
584	fn next_entry_seed<K, V>(
585		&mut self,
586		kseed: K,
587		vseed: V,
588	) -> Result<Option<(K::Value, V::Value)>, Self::Error>
589	where
590		K: serde::de::DeserializeSeed<'de>,
591		V: serde::de::DeserializeSeed<'de>,
592	{
593		if let Some((key, value)) = self.0.pop_front() {
594			let key = kseed.deserialize(ValueDeserializer(key))?;
595			let value = vseed.deserialize(ValueDeserializer(value))?;
596			Ok(Some((key, value)))
597		} else {
598			Ok(None)
599		}
600	}
601}
602
603/// Visit the integer, depending on its value / size.
604#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(visitor)))]
605fn visit_integer<'de, V>(int: Integer, visitor: V) -> Result<V::Value>
606where
607	V: ::serde::de::Visitor<'de>,
608{
609	#[allow(clippy::cast_lossless, reason = "We won't change it")]
610	#[allow(clippy::cast_possible_truncation, reason = "Integer casting is necessary")]
611	match int {
612		Integer::Unsigned(int) if int <= u8::MAX as u128 => visitor.visit_u8(int as u8),
613		Integer::Unsigned(int) if int <= u16::MAX as u128 => visitor.visit_u16(int as u16),
614		Integer::Unsigned(int) if int <= u32::MAX as u128 => visitor.visit_u32(int as u32),
615		Integer::Unsigned(int) if int <= u64::MAX as u128 => visitor.visit_u64(int as u64),
616		Integer::Unsigned(int) => visitor.visit_u128(int),
617		Integer::Signed(int) if (i8::MIN as i128 ..= i8::MAX as i128).contains(&int) => {
618			visitor.visit_i8(int as i8)
619		}
620		Integer::Signed(int) if (i16::MIN as i128 ..= i16::MAX as i128).contains(&int) => {
621			visitor.visit_i16(int as i16)
622		}
623		Integer::Signed(int) if (i32::MIN as i128 ..= i32::MAX as i128).contains(&int) => {
624			visitor.visit_i32(int as i32)
625		}
626		Integer::Signed(int) if (i64::MIN as i128 ..= i64::MAX as i128).contains(&int) => {
627			visitor.visit_i64(int as i64)
628		}
629		Integer::Signed(int) => visitor.visit_i128(int),
630	}
631}
632
633impl<'a, 'de> From<&'a Value<'de>> for Unexpected<'a> {
634	fn from(value: &'a Value<'de>) -> Self {
635		#[allow(clippy::cast_possible_truncation, reason = "Integer casting is necessary")]
636		match value {
637			Value::Null => Unexpected::Unit,
638			Value::Bool(b) => Unexpected::Bool(*b),
639			Value::Integer(Integer::Unsigned(int)) => Unexpected::Unsigned(*int as u64),
640			Value::Integer(Integer::Signed(int)) => Unexpected::Signed(*int as i64),
641			Value::Float(Float::F32(float)) => Unexpected::Float(f64::from(*float)),
642			Value::Float(Float::F64(float)) => Unexpected::Float(*float),
643			Value::Bytes(bytes) => Unexpected::Bytes(bytes),
644			Value::String(s) => Unexpected::Str(s),
645			Value::Array(_arr) => Unexpected::Seq,
646			Value::Map(_map) => Unexpected::Map,
647		}
648	}
649}