Skip to main content

cbor_core/ext/
serde.rs

1//! Serde integration for CBOR [`Value`].
2//!
3//! This module provides [`Serialize`] and [`Deserialize`] implementations
4//! for [`Value`], as well as the convenience functions [`to_value`] and
5//! [`from_value`] for converting between arbitrary Rust types and
6//! [`Value`] through serde.
7//!
8//! # Converting Rust types to `Value`
9//!
10//! Any type that implements [`Serialize`] can be converted into a
11//! [`Value`] with [`to_value`]:
12//!
13//! ```
14//! use cbor_core::serde::to_value;
15//!
16//! #[derive(serde::Serialize)]
17//! struct Sensor {
18//!     id: u32,
19//!     label: String,
20//!     readings: Vec<f64>,
21//! }
22//!
23//! let s = Sensor {
24//!     id: 7,
25//!     label: "temperature".into(),
26//!     readings: vec![20.5, 21.0, 19.8],
27//! };
28//!
29//! let v = to_value(&s).unwrap();
30//! assert_eq!(v["id"].to_u32().unwrap(), 7);
31//! assert_eq!(v["label"].as_str().unwrap(), "temperature");
32//! assert_eq!(v["readings"][0].to_f64().unwrap(), 20.5);
33//! ```
34//!
35//! # Converting `Value` to Rust types
36//!
37//! [`from_value`] goes the other direction, extracting a
38//! [`Deserialize`] type from a [`Value`]:
39//!
40//! ```
41//! use cbor_core::{Value, map, array};
42//! use cbor_core::serde::from_value;
43//!
44//! #[derive(serde::Deserialize, Debug, PartialEq)]
45//! struct Sensor {
46//!     id: u32,
47//!     label: String,
48//!     readings: Vec<f64>,
49//! }
50//!
51//! let v = map! {
52//!     "id" => 7,
53//!     "label" => "temperature",
54//!     "readings" => array![20.5, 21.0, 19.8],
55//! };
56//!
57//! let s: Sensor = from_value(&v).unwrap();
58//! assert_eq!(s.id, 7);
59//! assert_eq!(s.label, "temperature");
60//! ```
61//!
62//! # Serializing `Value` with other formats
63//!
64//! Because [`Value`] implements [`Serialize`] and [`Deserialize`], it
65//! works directly with any serde-based format such as JSON:
66//!
67//! ```
68//! use cbor_core::{Value, map};
69//!
70//! let v = map! { "x" => 1, "y" => 2 };
71//! let json = serde_json::to_string(&v).unwrap();
72//!
73//! let back: Value = serde_json::from_str(&json).unwrap();
74//! assert_eq!(back["x"].to_i32().unwrap(), 1);
75//! ```
76//!
77//! # Tags and CBOR-specific types
78//!
79//! The serde data model does not have a notion of CBOR tags or simple
80//! values. During deserialization, tags are stripped and their inner
81//! content is used directly — with the exception of big integers
82//! (tags 2 and 3), which are recognized and deserialized as integers.
83//! During serialization, tags are only emitted for big integers that
84//! exceed the `u64`/`i64` range; all other values are untagged.
85//!
86//! Tagged values and arbitrary simple values cannot be created through
87//! the serde interface. For full control over the encoded CBOR
88//! structure, build [`Value`]s directly using the constructors on
89//! [`Value`] (e.g. [`Value::tag`], [`Value::simple_value`]).
90
91use std::collections::BTreeMap;
92use std::fmt;
93
94use serde::de::{self, DeserializeSeed, Deserializer as _, MapAccess, SeqAccess, Visitor};
95use serde::ser::{self, SerializeMap, SerializeSeq};
96use serde::{Deserialize, Serialize};
97
98use crate::Value;
99
100// ---------------------------------------------------------------------------
101// Error
102// ---------------------------------------------------------------------------
103
104/// Error type returned by serde operations on [`Value`].
105///
106/// This is a string-based error type, separate from [`crate::Error`],
107/// because serde requires error types to support arbitrary messages
108/// via [`ser::Error::custom`] and [`de::Error::custom`].
109#[derive(Debug, Clone)]
110pub struct Error(String);
111
112impl fmt::Display for Error {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        self.0.fmt(f)
115    }
116}
117
118impl std::error::Error for Error {}
119
120impl ser::Error for Error {
121    fn custom<T: fmt::Display>(msg: T) -> Self {
122        Error(msg.to_string())
123    }
124}
125
126impl de::Error for Error {
127    fn custom<T: fmt::Display>(msg: T) -> Self {
128        Error(msg.to_string())
129    }
130}
131
132impl From<crate::Error> for Error {
133    fn from(error: crate::Error) -> Self {
134        Error(error.to_string())
135    }
136}
137
138// ---------------------------------------------------------------------------
139// Public API
140// ---------------------------------------------------------------------------
141
142/// Convert any `Serialize` value into a CBOR [`Value`].
143///
144/// ```
145/// use cbor_core::Value;
146/// use cbor_core::serde::to_value;
147///
148/// #[derive(serde::Serialize)]
149/// struct Point { x: i32, y: i32 }
150///
151/// let v = to_value(&Point { x: 1, y: 2 }).unwrap();
152/// assert_eq!(v["x"].to_i32().unwrap(), 1);
153/// assert_eq!(v["y"].to_i32().unwrap(), 2);
154/// ```
155pub fn to_value<T: Serialize + ?Sized>(value: &T) -> Result<Value, Error> {
156    value.serialize(ValueSerializer)
157}
158
159/// Convert a CBOR [`Value`] into any `Deserialize` type.
160///
161/// ```
162/// use cbor_core::{Value, map};
163/// use cbor_core::serde::from_value;
164///
165/// #[derive(serde::Deserialize, Debug, PartialEq)]
166/// struct Point { x: i32, y: i32 }
167///
168/// let v = map! { "x" => 1, "y" => 2 };
169/// let p: Point = from_value(&v).unwrap();
170/// assert_eq!(p, Point { x: 1, y: 2 });
171/// ```
172pub fn from_value<'de, T: Deserialize<'de>>(value: &'de Value) -> Result<T, Error> {
173    T::deserialize(ValueDeserializer(value))
174}
175
176// ---------------------------------------------------------------------------
177// Serialize impl for Value
178// ---------------------------------------------------------------------------
179
180impl Serialize for Value {
181    fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
182        match self {
183            Value::SimpleValue(sv) => match sv.data_type() {
184                crate::DataType::Null => serializer.serialize_unit(),
185                crate::DataType::Bool => serializer.serialize_bool(sv.to_bool().unwrap()),
186                _ => serializer.serialize_u8(sv.to_u8()),
187            },
188            Value::Unsigned(n) => serializer.serialize_u64(*n),
189            Value::Negative(n) => {
190                // actual value = -1 - n
191                if let Ok(v) = i64::try_from(*n).map(|v| !v) {
192                    serializer.serialize_i64(v)
193                } else {
194                    serializer.serialize_i128(!(*n as i128))
195                }
196            }
197            Value::Float(float) => serializer.serialize_f64(float.to_f64()),
198            Value::ByteString(b) => serializer.serialize_bytes(b),
199            Value::TextString(s) => serializer.serialize_str(s),
200            Value::Array(arr) => {
201                let mut seq = serializer.serialize_seq(Some(arr.len()))?;
202                for item in arr {
203                    seq.serialize_element(item)?;
204                }
205                seq.end()
206            }
207            Value::Map(map) => {
208                let mut m = serializer.serialize_map(Some(map.len()))?;
209                for (k, v) in map {
210                    m.serialize_entry(k, v)?;
211                }
212                m.end()
213            }
214            // Tags are transparent — serialize the inner content.
215            Value::Tag(_, content) => content.serialize(serializer),
216        }
217    }
218}
219
220// ---------------------------------------------------------------------------
221// Deserialize impl for Value
222// ---------------------------------------------------------------------------
223
224impl<'de> Deserialize<'de> for Value {
225    fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
226        deserializer.deserialize_any(ValueVisitor)
227    }
228}
229
230struct ValueVisitor;
231
232macro_rules! visit {
233    ($method:ident, $type:ty) => {
234        fn $method<E>(self, v: $type) -> Result<Value, E> {
235            Ok(Value::from(v))
236        }
237    };
238}
239
240impl<'de> Visitor<'de> for ValueVisitor {
241    type Value = Value;
242
243    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
244        f.write_str("any CBOR-compatible value")
245    }
246
247    visit!(visit_bool, bool);
248
249    visit!(visit_i8, i8);
250    visit!(visit_i16, i16);
251    visit!(visit_i32, i32);
252    visit!(visit_i64, i64);
253    visit!(visit_i128, i128);
254
255    visit!(visit_u8, u8);
256    visit!(visit_u16, u16);
257    visit!(visit_u32, u32);
258    visit!(visit_u64, u64);
259    visit!(visit_u128, u128);
260
261    visit!(visit_f32, f32);
262    visit!(visit_f64, f64);
263
264    fn visit_char<E>(self, v: char) -> Result<Value, E> {
265        Ok(Value::from(v.to_string()))
266    }
267
268    visit!(visit_str, &str);
269    visit!(visit_string, String);
270
271    visit!(visit_bytes, &[u8]);
272    visit!(visit_byte_buf, Vec<u8>);
273
274    fn visit_none<E>(self) -> Result<Value, E> {
275        Ok(Value::null())
276    }
277
278    fn visit_some<D: de::Deserializer<'de>>(self, deserializer: D) -> Result<Value, D::Error> {
279        Deserialize::deserialize(deserializer)
280    }
281
282    fn visit_unit<E>(self) -> Result<Value, E> {
283        Ok(Value::null())
284    }
285
286    fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Value, A::Error> {
287        let mut elements = Vec::with_capacity(access.size_hint().unwrap_or(0));
288        while let Some(elem) = access.next_element()? {
289            elements.push(elem);
290        }
291        Ok(Value::Array(elements))
292    }
293
294    fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Value, A::Error> {
295        let mut map = BTreeMap::new();
296        while let Some((k, v)) = access.next_entry()? {
297            map.insert(k, v);
298        }
299        Ok(Value::Map(map))
300    }
301}
302
303// ---------------------------------------------------------------------------
304// ValueSerializer: Rust → Value
305// ---------------------------------------------------------------------------
306
307/// Serde `Serializer` that produces a CBOR [`Value`].
308struct ValueSerializer;
309
310macro_rules! serialize {
311    ($method:ident, $type:ty) => {
312        fn $method(self, v: $type) -> Result<Value, Error> {
313            Ok(Value::from(v))
314        }
315    };
316}
317
318impl ser::Serializer for ValueSerializer {
319    type Ok = Value;
320    type Error = Error;
321
322    type SerializeSeq = SeqBuilder;
323    type SerializeTuple = SeqBuilder;
324    type SerializeTupleStruct = SeqBuilder;
325    type SerializeTupleVariant = TupleVariantBuilder;
326    type SerializeMap = MapBuilder;
327    type SerializeStruct = MapBuilder;
328    type SerializeStructVariant = StructVariantBuilder;
329
330    serialize!(serialize_bool, bool);
331
332    serialize!(serialize_i8, i8);
333    serialize!(serialize_i16, i16);
334    serialize!(serialize_i32, i32);
335    serialize!(serialize_i64, i64);
336    serialize!(serialize_i128, i128);
337
338    serialize!(serialize_u8, u8);
339    serialize!(serialize_u16, u16);
340    serialize!(serialize_u32, u32);
341    serialize!(serialize_u64, u64);
342    serialize!(serialize_u128, u128);
343
344    serialize!(serialize_f32, f32);
345    serialize!(serialize_f64, f64);
346
347    fn serialize_char(self, v: char) -> Result<Value, Error> {
348        Ok(Value::from(v.to_string()))
349    }
350
351    serialize!(serialize_str, &str);
352    serialize!(serialize_bytes, &[u8]);
353
354    fn serialize_none(self) -> Result<Value, Error> {
355        Ok(Value::null())
356    }
357
358    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Value, Error> {
359        value.serialize(self)
360    }
361
362    fn serialize_unit(self) -> Result<Value, Error> {
363        Ok(Value::null())
364    }
365
366    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
367        Ok(Value::null())
368    }
369
370    fn serialize_unit_variant(
371        self,
372        _name: &'static str,
373        _variant_index: u32,
374        variant: &'static str,
375    ) -> Result<Value, Error> {
376        Ok(Value::from(variant))
377    }
378
379    fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _name: &'static str, value: &T) -> Result<Value, Error> {
380        value.serialize(self)
381    }
382
383    fn serialize_newtype_variant<T: ?Sized + Serialize>(
384        self,
385        _name: &'static str,
386        _variant_index: u32,
387        variant: &'static str,
388        value: &T,
389    ) -> Result<Value, Error> {
390        Ok(Value::map([(variant, to_value(value)?)]))
391    }
392
393    fn serialize_seq(self, len: Option<usize>) -> Result<SeqBuilder, Error> {
394        Ok(SeqBuilder {
395            elements: Vec::with_capacity(len.unwrap_or(0)),
396        })
397    }
398
399    fn serialize_tuple(self, len: usize) -> Result<SeqBuilder, Error> {
400        self.serialize_seq(Some(len))
401    }
402
403    fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqBuilder, Error> {
404        self.serialize_seq(Some(len))
405    }
406
407    fn serialize_tuple_variant(
408        self,
409        _name: &'static str,
410        _variant_index: u32,
411        variant: &'static str,
412        len: usize,
413    ) -> Result<TupleVariantBuilder, Error> {
414        Ok(TupleVariantBuilder {
415            variant,
416            elements: Vec::with_capacity(len),
417        })
418    }
419
420    fn serialize_map(self, len: Option<usize>) -> Result<MapBuilder, Error> {
421        let _ = len; // BTreeMap doesn't pre-allocate
422        Ok(MapBuilder {
423            entries: BTreeMap::new(),
424            next_key: None,
425        })
426    }
427
428    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapBuilder, Error> {
429        self.serialize_map(Some(len))
430    }
431
432    fn serialize_struct_variant(
433        self,
434        _name: &'static str,
435        _variant_index: u32,
436        variant: &'static str,
437        _len: usize,
438    ) -> Result<StructVariantBuilder, Error> {
439        Ok(StructVariantBuilder {
440            variant,
441            entries: BTreeMap::new(),
442        })
443    }
444}
445
446// --- Serializer helpers ---
447
448struct SeqBuilder {
449    elements: Vec<Value>,
450}
451
452impl SerializeSeq for SeqBuilder {
453    type Ok = Value;
454    type Error = Error;
455
456    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
457        self.elements.push(to_value(value)?);
458        Ok(())
459    }
460
461    fn end(self) -> Result<Value, Error> {
462        Ok(Value::Array(self.elements))
463    }
464}
465
466impl ser::SerializeTuple for SeqBuilder {
467    type Ok = Value;
468    type Error = Error;
469
470    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
471        SerializeSeq::serialize_element(self, value)
472    }
473
474    fn end(self) -> Result<Value, Error> {
475        SerializeSeq::end(self)
476    }
477}
478
479impl ser::SerializeTupleStruct for SeqBuilder {
480    type Ok = Value;
481    type Error = Error;
482
483    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
484        SerializeSeq::serialize_element(self, value)
485    }
486
487    fn end(self) -> Result<Value, Error> {
488        SerializeSeq::end(self)
489    }
490}
491
492struct TupleVariantBuilder {
493    variant: &'static str,
494    elements: Vec<Value>,
495}
496
497impl ser::SerializeTupleVariant for TupleVariantBuilder {
498    type Ok = Value;
499    type Error = Error;
500
501    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
502        self.elements.push(to_value(value)?);
503        Ok(())
504    }
505
506    fn end(self) -> Result<Value, Error> {
507        Ok(Value::map([(self.variant, self.elements)]))
508    }
509}
510
511struct MapBuilder {
512    entries: BTreeMap<Value, Value>,
513    next_key: Option<Value>,
514}
515
516impl SerializeMap for MapBuilder {
517    type Ok = Value;
518    type Error = Error;
519
520    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Error> {
521        self.next_key = Some(to_value(key)?);
522        Ok(())
523    }
524
525    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
526        let key = self
527            .next_key
528            .take()
529            .ok_or_else(|| Error("serialize_value called before serialize_key".into()))?;
530        self.entries.insert(key, to_value(value)?);
531        Ok(())
532    }
533
534    fn end(self) -> Result<Value, Error> {
535        Ok(Value::Map(self.entries))
536    }
537}
538
539impl ser::SerializeStruct for MapBuilder {
540    type Ok = Value;
541    type Error = Error;
542
543    fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
544        self.entries.insert(Value::from(key), to_value(value)?);
545        Ok(())
546    }
547
548    fn end(self) -> Result<Value, Error> {
549        Ok(Value::Map(self.entries))
550    }
551}
552
553struct StructVariantBuilder {
554    variant: &'static str,
555    entries: BTreeMap<Value, Value>,
556}
557
558impl ser::SerializeStructVariant for StructVariantBuilder {
559    type Ok = Value;
560    type Error = Error;
561
562    fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Error> {
563        self.entries.insert(Value::from(key), to_value(value)?);
564        Ok(())
565    }
566
567    fn end(self) -> Result<Value, Error> {
568        Ok(Value::map([(self.variant, self.entries)]))
569    }
570}
571
572// ---------------------------------------------------------------------------
573// ValueDeserializer: &Value → Rust
574// ---------------------------------------------------------------------------
575
576/// Serde `Deserializer` that reads from a CBOR [`Value`] reference.
577struct ValueDeserializer<'de>(&'de Value);
578
579macro_rules! deserialize {
580    ($method:ident, $visit:ident) => {
581        fn $method<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
582            visitor.$visit(self.0.try_into()?)
583        }
584    };
585}
586
587impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> {
588    type Error = Error;
589
590    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
591        let this = self.0.peeled();
592        if let Value::SimpleValue(sv) = this {
593            if sv.data_type().is_null() {
594                visitor.visit_unit()
595            } else if let Ok(v) = sv.to_bool() {
596                visitor.visit_bool(v)
597            } else {
598                visitor.visit_u8(sv.to_u8())
599            }
600        } else if let Ok(v) = this.to_u64() {
601            visitor.visit_u64(v)
602        } else if let Ok(v) = this.to_i64() {
603            visitor.visit_i64(v)
604        } else if let Ok(v) = this.to_u128() {
605            visitor.visit_u128(v)
606        } else if let Ok(v) = this.to_i128() {
607            visitor.visit_i128(v)
608        } else if let Ok(v) = this.to_f32() {
609            visitor.visit_f32(v)
610        } else if let Ok(v) = this.to_f64() {
611            visitor.visit_f64(v)
612        } else if let Ok(v) = this.as_bytes() {
613            visitor.visit_borrowed_bytes(v)
614        } else if let Ok(v) = this.as_str() {
615            visitor.visit_borrowed_str(v)
616        } else {
617            match this.untagged() {
618                Value::Array(arr) => visitor.visit_seq(SeqAccessImpl(arr.iter())),
619                Value::Map(map) => visitor.visit_map(MapAccessImpl {
620                    iter: map.iter(),
621                    pending_value: None,
622                }),
623                _other => unreachable!(),
624            }
625        }
626    }
627
628    deserialize!(deserialize_bool, visit_bool);
629
630    deserialize!(deserialize_i8, visit_i8);
631    deserialize!(deserialize_i16, visit_i16);
632    deserialize!(deserialize_i32, visit_i32);
633    deserialize!(deserialize_i64, visit_i64);
634    deserialize!(deserialize_i128, visit_i128);
635
636    deserialize!(deserialize_u8, visit_u8);
637    deserialize!(deserialize_u16, visit_u16);
638    deserialize!(deserialize_u32, visit_u32);
639    deserialize!(deserialize_u64, visit_u64);
640    deserialize!(deserialize_u128, visit_u128);
641
642    fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
643        visitor.visit_f32(self.0.to_f64()? as f32)
644    }
645
646    deserialize!(deserialize_f64, visit_f64);
647
648    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
649        let s = self.0.as_str()?;
650        let mut chars = s.chars();
651        let ch = chars.next().ok_or_else(|| Error("empty string for char".into()))?;
652        if chars.next().is_some() {
653            return Err(Error("string contains more than one char".into()));
654        }
655        visitor.visit_char(ch)
656    }
657
658    deserialize!(deserialize_str, visit_borrowed_str);
659    deserialize!(deserialize_string, visit_borrowed_str);
660
661    deserialize!(deserialize_bytes, visit_borrowed_bytes);
662    deserialize!(deserialize_byte_buf, visit_borrowed_bytes);
663
664    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
665        if self.0.untagged().data_type().is_null() {
666            visitor.visit_none()
667        } else {
668            visitor.visit_some(self)
669        }
670    }
671
672    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
673        if self.0.untagged().data_type().is_null() {
674            visitor.visit_unit()
675        } else {
676            Err(de::Error::custom(format!(
677                "expected null, got {}",
678                self.0.data_type().name()
679            )))
680        }
681    }
682
683    fn deserialize_unit_struct<V: Visitor<'de>>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error> {
684        self.deserialize_unit(visitor)
685    }
686
687    fn deserialize_newtype_struct<V: Visitor<'de>>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error> {
688        visitor.visit_newtype_struct(self)
689    }
690
691    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
692        match self.0.untagged() {
693            Value::Array(arr) => visitor.visit_seq(SeqAccessImpl(arr.iter())),
694            other => Err(de::Error::custom(format!(
695                "expected array, got {}",
696                other.data_type().name()
697            ))),
698        }
699    }
700
701    fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Error> {
702        self.deserialize_seq(visitor)
703    }
704
705    fn deserialize_tuple_struct<V: Visitor<'de>>(
706        self,
707        _name: &'static str,
708        _len: usize,
709        visitor: V,
710    ) -> Result<V::Value, Error> {
711        self.deserialize_seq(visitor)
712    }
713
714    fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
715        match self.0.untagged() {
716            Value::Map(map) => visitor.visit_map(MapAccessImpl {
717                iter: map.iter(),
718                pending_value: None,
719            }),
720            other => Err(de::Error::custom(format!(
721                "expected map, got {}",
722                other.data_type().name()
723            ))),
724        }
725    }
726
727    fn deserialize_struct<V: Visitor<'de>>(
728        self,
729        _name: &'static str,
730        _fields: &'static [&'static str],
731        visitor: V,
732    ) -> Result<V::Value, Error> {
733        self.deserialize_map(visitor)
734    }
735
736    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
737        match self.0.untagged() {
738            Value::TextString(s) => visitor.visit_borrowed_str(s),
739            other => Err(de::Error::custom(format!(
740                "expected string identifier, got {}",
741                other.data_type().name()
742            ))),
743        }
744    }
745
746    fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
747        visitor.visit_unit()
748    }
749
750    fn deserialize_enum<V: Visitor<'de>>(
751        self,
752        _name: &'static str,
753        _variants: &'static [&'static str],
754        visitor: V,
755    ) -> Result<V::Value, Error> {
756        match self.0.untagged() {
757            // Unit variant: "VariantName"
758            Value::TextString(variant) => visitor.visit_enum(de::value::StrDeserializer::new(variant)),
759
760            // Newtype / tuple / struct variant: { "VariantName": payload }
761            Value::Map(map) if map.len() == 1 => {
762                let (k, v) = map.iter().next().unwrap();
763                let variant = k.as_str()?;
764                visitor.visit_enum(EnumAccessImpl { variant, value: v })
765            }
766
767            other => Err(de::Error::custom(format!(
768                "expected string or single-entry map for enum, got {}",
769                other.data_type().name()
770            ))),
771        }
772    }
773}
774
775// ---------------------------------------------------------------------------
776// SeqAccess / MapAccess
777// ---------------------------------------------------------------------------
778
779struct SeqAccessImpl<'de>(std::slice::Iter<'de, Value>);
780
781impl<'de> SeqAccess<'de> for SeqAccessImpl<'de> {
782    type Error = Error;
783
784    fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>, Error> {
785        match self.0.next() {
786            Some(v) => seed.deserialize(ValueDeserializer(v)).map(Some),
787            None => Ok(None),
788        }
789    }
790
791    fn size_hint(&self) -> Option<usize> {
792        Some(self.0.len())
793    }
794}
795
796struct MapAccessImpl<'de> {
797    iter: std::collections::btree_map::Iter<'de, Value, Value>,
798    pending_value: Option<&'de Value>,
799}
800
801impl<'de> MapAccess<'de> for MapAccessImpl<'de> {
802    type Error = Error;
803
804    fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>, Error> {
805        match self.iter.next() {
806            Some((k, v)) => {
807                self.pending_value = Some(v);
808                seed.deserialize(ValueDeserializer(k)).map(Some)
809            }
810            None => Ok(None),
811        }
812    }
813
814    fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value, Error> {
815        let v = self
816            .pending_value
817            .take()
818            .ok_or_else(|| Error("next_value_seed called before next_key_seed".into()))?;
819        seed.deserialize(ValueDeserializer(v))
820    }
821
822    fn size_hint(&self) -> Option<usize> {
823        Some(self.iter.len())
824    }
825}
826
827// ---------------------------------------------------------------------------
828// EnumAccess / VariantAccess
829// ---------------------------------------------------------------------------
830
831struct EnumAccessImpl<'de> {
832    variant: &'de str,
833    value: &'de Value,
834}
835
836impl<'de> de::EnumAccess<'de> for EnumAccessImpl<'de> {
837    type Error = Error;
838    type Variant = VariantAccessImpl<'de>;
839
840    fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant), Error> {
841        let variant = seed.deserialize(de::value::StrDeserializer::<Error>::new(self.variant))?;
842        Ok((variant, VariantAccessImpl(self.value)))
843    }
844}
845
846struct VariantAccessImpl<'de>(&'de Value);
847
848impl<'de> de::VariantAccess<'de> for VariantAccessImpl<'de> {
849    type Error = Error;
850
851    fn unit_variant(self) -> Result<(), Error> {
852        if self.0.untagged().data_type().is_null() {
853            Ok(())
854        } else {
855            Err(Error(format!(
856                "expected null for unit variant, got {}",
857                self.0.data_type().name()
858            )))
859        }
860    }
861
862    fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value, Error> {
863        seed.deserialize(ValueDeserializer(self.0))
864    }
865
866    fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Error> {
867        ValueDeserializer(self.0).deserialize_seq(visitor)
868    }
869
870    fn struct_variant<V: Visitor<'de>>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value, Error> {
871        ValueDeserializer(self.0).deserialize_map(visitor)
872    }
873}
874
875// ---------------------------------------------------------------------------
876// Tests
877// ---------------------------------------------------------------------------
878
879#[cfg(test)]
880mod tests {
881    use super::*;
882    use crate::{array, map};
883
884    // --- Round-trip: primitives ---
885
886    #[test]
887    fn round_trip_bool() {
888        let v = to_value(&true).unwrap();
889        assert!(v.to_bool().unwrap());
890        assert!(from_value::<bool>(&v).unwrap());
891
892        let v = to_value(&false).unwrap();
893        assert!(!from_value::<bool>(&v).unwrap());
894    }
895
896    #[test]
897    fn round_trip_unsigned() {
898        let v = to_value(&42_u32).unwrap();
899        assert_eq!(v.to_u64().unwrap(), 42);
900        assert_eq!(from_value::<u32>(&v).unwrap(), 42);
901    }
902
903    #[test]
904    fn round_trip_signed_positive() {
905        let v = to_value(&100_i64).unwrap();
906        assert_eq!(from_value::<i64>(&v).unwrap(), 100);
907    }
908
909    #[test]
910    fn round_trip_signed_negative() {
911        let v = to_value(&-42_i32).unwrap();
912        assert_eq!(from_value::<i32>(&v).unwrap(), -42);
913    }
914
915    #[test]
916    fn round_trip_float() {
917        let v = to_value(&3.42_f64).unwrap();
918        assert_eq!(from_value::<f64>(&v).unwrap(), 3.42);
919    }
920
921    #[test]
922    fn round_trip_string() {
923        let v = to_value("hello").unwrap();
924        assert_eq!(v.as_str().unwrap(), "hello");
925        assert_eq!(from_value::<String>(&v).unwrap(), "hello");
926    }
927
928    #[test]
929    fn round_trip_bytes() {
930        let data = vec![1_u8, 2, 3];
931        let v = to_value(&serde_bytes::Bytes::new(&data)).unwrap();
932        assert_eq!(v.as_bytes().unwrap(), &[1, 2, 3]);
933        let back: serde_bytes::ByteBuf = from_value(&v).unwrap();
934        assert_eq!(back.as_ref(), &[1, 2, 3]);
935    }
936
937    #[test]
938    fn round_trip_none() {
939        let v = to_value(&Option::<i32>::None).unwrap();
940        assert!(v.data_type().is_null());
941        assert_eq!(from_value::<Option<i32>>(&v).unwrap(), None);
942    }
943
944    #[test]
945    fn round_trip_some() {
946        let v = to_value(&Some(42_u32)).unwrap();
947        assert_eq!(from_value::<Option<u32>>(&v).unwrap(), Some(42));
948    }
949
950    // --- Round-trip: collections ---
951
952    #[test]
953    fn round_trip_vec() {
954        let v = to_value(&vec![1_u32, 2, 3]).unwrap();
955        assert_eq!(from_value::<Vec<u32>>(&v).unwrap(), vec![1, 2, 3]);
956    }
957
958    #[test]
959    fn round_trip_map() {
960        let mut m = std::collections::BTreeMap::new();
961        m.insert("a".to_string(), 1_u32);
962        m.insert("b".to_string(), 2);
963        let v = to_value(&m).unwrap();
964        let back: std::collections::BTreeMap<String, u32> = from_value(&v).unwrap();
965        assert_eq!(back, m);
966    }
967
968    // --- Round-trip: structs ---
969
970    #[test]
971    fn round_trip_struct() {
972        #[derive(Serialize, Deserialize, Debug, PartialEq)]
973        struct Point {
974            x: i32,
975            y: i32,
976        }
977
978        let p = Point { x: 10, y: -20 };
979        let v = to_value(&p).unwrap();
980        assert_eq!(v["x"].to_i32().unwrap(), 10);
981        assert_eq!(v["y"].to_i32().unwrap(), -20);
982        let back: Point = from_value(&v).unwrap();
983        assert_eq!(back, p);
984    }
985
986    #[test]
987    fn round_trip_nested_struct() {
988        #[derive(Serialize, Deserialize, Debug, PartialEq)]
989        struct Inner {
990            value: String,
991        }
992        #[derive(Serialize, Deserialize, Debug, PartialEq)]
993        struct Outer {
994            name: String,
995            inner: Inner,
996        }
997
998        let o = Outer {
999            name: "test".into(),
1000            inner: Inner { value: "nested".into() },
1001        };
1002        let v = to_value(&o).unwrap();
1003        let back: Outer = from_value(&v).unwrap();
1004        assert_eq!(back, o);
1005    }
1006
1007    // --- Round-trip: enums ---
1008
1009    #[test]
1010    fn round_trip_unit_variant() {
1011        #[derive(Serialize, Deserialize, Debug, PartialEq)]
1012        enum Color {
1013            Red,
1014            Green,
1015            Blue,
1016        }
1017
1018        let v = to_value(&Color::Green).unwrap();
1019        assert_eq!(v.as_str().unwrap(), "Green");
1020        let back: Color = from_value(&v).unwrap();
1021        assert_eq!(back, Color::Green);
1022    }
1023
1024    #[test]
1025    fn round_trip_newtype_variant() {
1026        #[derive(Serialize, Deserialize, Debug, PartialEq)]
1027        enum Shape {
1028            Circle(f64),
1029            Square(f64),
1030        }
1031
1032        let v = to_value(&Shape::Circle(2.5)).unwrap();
1033        let back: Shape = from_value(&v).unwrap();
1034        assert_eq!(back, Shape::Circle(2.5));
1035    }
1036
1037    #[test]
1038    fn round_trip_struct_variant() {
1039        #[derive(Serialize, Deserialize, Debug, PartialEq)]
1040        enum Message {
1041            Quit,
1042            Move { x: i32, y: i32 },
1043        }
1044
1045        let v = to_value(&Message::Move { x: 1, y: 2 }).unwrap();
1046        let back: Message = from_value(&v).unwrap();
1047        assert_eq!(back, Message::Move { x: 1, y: 2 });
1048    }
1049
1050    #[test]
1051    fn round_trip_tuple_variant() {
1052        #[derive(Serialize, Deserialize, Debug, PartialEq)]
1053        enum Pair {
1054            Two(i32, i32),
1055        }
1056
1057        let v = to_value(&Pair::Two(3, 4)).unwrap();
1058        let back: Pair = from_value(&v).unwrap();
1059        assert_eq!(back, Pair::Two(3, 4));
1060    }
1061
1062    // --- Deserialize from hand-built Value ---
1063
1064    #[test]
1065    fn from_value_hand_built() {
1066        #[derive(Deserialize, Debug, PartialEq)]
1067        struct Record {
1068            id: u64,
1069            name: String,
1070            active: bool,
1071        }
1072
1073        let v = map! {
1074            "id" => 42,
1075            "name" => "alice",
1076            "active" => true,
1077        };
1078
1079        let r: Record = from_value(&v).unwrap();
1080        assert_eq!(
1081            r,
1082            Record {
1083                id: 42,
1084                name: "alice".into(),
1085                active: true,
1086            }
1087        );
1088    }
1089
1090    // --- Serialize Value itself ---
1091
1092    #[test]
1093    fn serialize_value_null() {
1094        let v = Value::null();
1095        let json = serde_json::to_string(&v).unwrap();
1096        assert_eq!(json, "null");
1097    }
1098
1099    #[test]
1100    fn serialize_value_integer() {
1101        let v = Value::from(42_u64);
1102        let json = serde_json::to_string(&v).unwrap();
1103        assert_eq!(json, "42");
1104    }
1105
1106    #[test]
1107    fn serialize_value_negative() {
1108        let v = Value::from(-10_i64);
1109        let json = serde_json::to_string(&v).unwrap();
1110        assert_eq!(json, "-10");
1111    }
1112
1113    #[test]
1114    fn serialize_value_array() {
1115        let v = array![1, 2, 3];
1116        let json = serde_json::to_string(&v).unwrap();
1117        assert_eq!(json, "[1,2,3]");
1118    }
1119
1120    #[test]
1121    fn serialize_value_map() {
1122        let v = map! { "a" => 1 };
1123        let json = serde_json::to_string(&v).unwrap();
1124        assert_eq!(json, "{\"a\":1}");
1125    }
1126
1127    // --- Tags are transparent ---
1128
1129    #[test]
1130    fn tagged_value_transparent_deserialize() {
1131        // Tag wrapping an integer — should deserialize as if untagged.
1132        let v = Value::tag(42, 100_u64);
1133        let n: u64 = from_value(&v).unwrap();
1134        assert_eq!(n, 100);
1135    }
1136
1137    #[test]
1138    fn tagged_value_transparent_serialize() {
1139        let v = Value::tag(42, 100_u64);
1140        let json = serde_json::to_string(&v).unwrap();
1141        assert_eq!(json, "100");
1142    }
1143
1144    // --- Edge cases ---
1145
1146    #[test]
1147    fn large_negative_i128() {
1148        let big = i64::MIN as i128 - 1;
1149        let v = to_value(&big).unwrap();
1150        let back: i128 = from_value(&v).unwrap();
1151        assert_eq!(back, big);
1152    }
1153
1154    #[test]
1155    fn unit_type() {
1156        let v = to_value(&()).unwrap();
1157        assert!(v.data_type().is_null());
1158        from_value::<()>(&v).unwrap();
1159    }
1160
1161    #[test]
1162    fn char_round_trip() {
1163        let v = to_value(&'Z').unwrap();
1164        assert_eq!(from_value::<char>(&v).unwrap(), 'Z');
1165    }
1166
1167    #[test]
1168    fn empty_vec() {
1169        let v = to_value(&Vec::<i32>::new()).unwrap();
1170        assert_eq!(from_value::<Vec<i32>>(&v).unwrap(), Vec::<i32>::new());
1171    }
1172
1173    #[test]
1174    fn empty_map() {
1175        let v = to_value(&std::collections::BTreeMap::<String, i32>::new()).unwrap();
1176        let back: std::collections::BTreeMap<String, i32> = from_value(&v).unwrap();
1177        assert!(back.is_empty());
1178    }
1179
1180    #[test]
1181    fn deserialize_error_type_mismatch() {
1182        let v = Value::from("not a number");
1183        let result = from_value::<u32>(&v);
1184        assert!(result.is_err());
1185    }
1186
1187    #[test]
1188    fn deserialize_error_overflow() {
1189        let v = Value::from(1000_u64);
1190        let result = from_value::<u8>(&v);
1191        assert!(result.is_err());
1192    }
1193
1194    #[test]
1195    fn optional_field() {
1196        #[derive(Serialize, Deserialize, Debug, PartialEq)]
1197        struct Config {
1198            name: String,
1199            port: Option<u16>,
1200        }
1201
1202        let with = to_value(&Config {
1203            name: "srv".into(),
1204            port: Some(8080),
1205        })
1206        .unwrap();
1207        let back: Config = from_value(&with).unwrap();
1208        assert_eq!(back.port, Some(8080));
1209
1210        let without = to_value(&Config {
1211            name: "srv".into(),
1212            port: None,
1213        })
1214        .unwrap();
1215        let back: Config = from_value(&without).unwrap();
1216        assert_eq!(back.port, None);
1217    }
1218
1219    #[test]
1220    fn tuple() {
1221        let v = to_value(&(1_u32, "hello", true)).unwrap();
1222        let back: (u32, String, bool) = from_value(&v).unwrap();
1223        assert_eq!(back, (1, "hello".into(), true));
1224    }
1225
1226    // --- Deserialize Value from JSON (proves Deserialize impl works) ---
1227
1228    #[test]
1229    fn deserialize_value_from_json() {
1230        let v: Value = serde_json::from_str(r#"{"key": [1, 2, 3]}"#).unwrap();
1231        let arr = v["key"].as_array().unwrap();
1232        assert_eq!(arr.len(), 3);
1233        assert_eq!(arr[0].to_u32().unwrap(), 1);
1234    }
1235}