Skip to main content

libmaxminddb_rs/
value.rs

1//! Owned and borrowed MMDB values.
2
3use std::collections::BTreeMap;
4
5use serde::ser::{self, Impossible, Serialize};
6
7use crate::{Error, Result};
8
9/// Borrowed representation of a decoded MMDB value.
10///
11/// String and byte payloads point directly into the source MMDB buffer. Arrays and maps
12/// allocate only their small container vectors; their scalar payloads remain borrowed.
13#[derive(Debug, Clone, PartialEq)]
14pub enum ValueRef<'a> {
15    /// Borrowed UTF-8 string.
16    Utf8(&'a str),
17    /// Borrowed byte string.
18    Bytes(&'a [u8]),
19    /// IEEE-754 64-bit floating-point value.
20    Double(f64),
21    /// IEEE-754 32-bit floating-point value.
22    Float(f32),
23    /// Unsigned 16-bit integer.
24    Uint16(u16),
25    /// Unsigned 32-bit integer.
26    Uint32(u32),
27    /// Signed 32-bit integer.
28    Int32(i32),
29    /// Unsigned 64-bit integer.
30    Uint64(u64),
31    /// Unsigned 128-bit integer.
32    Uint128(u128),
33    /// Boolean value.
34    Bool(bool),
35    /// Ordered MMDB array whose elements may borrow the source buffer.
36    Array(Vec<ValueRef<'a>>),
37    /// MMDB map represented as borrowed keys and borrowed/inline values.
38    Map(Vec<(&'a str, ValueRef<'a>)>),
39}
40
41impl<'a> ValueRef<'a> {
42    /// Gets a map field without allocating. Returns `None` for missing keys or
43    /// non-map values.
44    ///
45    /// # Examples
46    ///
47    /// ```rust
48    /// use libmaxminddb_rs::ValueRef;
49    /// let value = ValueRef::Map(vec![("asn", ValueRef::Uint32(64512))]);
50    /// assert_eq!(value.get("asn"), Some(&ValueRef::Uint32(64512)));
51    /// assert_eq!(value.get("missing"), None);
52    /// ```
53    #[must_use]
54    #[inline]
55    pub fn get(&self, key: &str) -> Option<&ValueRef<'a>> {
56        match self {
57            Self::Map(entries) => entries.iter().find_map(|(k, v)| (*k == key).then_some(v)),
58            _ => None,
59        }
60    }
61
62    /// Converts to an owned value. This copies strings, bytes, and container
63    /// contents so the result can outlive the MMDB buffer.
64    ///
65    /// # Examples
66    ///
67    /// ```rust
68    /// use libmaxminddb_rs::{Value, ValueRef};
69    /// let borrowed = ValueRef::Utf8("example");
70    /// assert_eq!(borrowed.to_owned_value(), Value::Utf8("example".into()));
71    /// ```
72    #[must_use]
73    pub fn to_owned_value(&self) -> Value {
74        match self {
75            Self::Utf8(v) => Value::Utf8((*v).to_owned()),
76            Self::Bytes(v) => Value::Bytes((*v).to_vec()),
77            Self::Double(v) => Value::Double(*v),
78            Self::Float(v) => Value::Float(*v),
79            Self::Uint16(v) => Value::Uint16(*v),
80            Self::Uint32(v) => Value::Uint32(*v),
81            Self::Int32(v) => Value::Int32(*v),
82            Self::Uint64(v) => Value::Uint64(*v),
83            Self::Uint128(v) => Value::Uint128(*v),
84            Self::Bool(v) => Value::Bool(*v),
85            Self::Array(v) => Value::Array(v.iter().map(Self::to_owned_value).collect()),
86            Self::Map(v) => Value::Map(
87                v.iter()
88                    .map(|(k, v)| ((*k).to_owned(), v.to_owned_value()))
89                    .collect(),
90            ),
91        }
92    }
93
94    /// Converts this value to JSON for serde-based owned deserialization.
95    /// The conversion allocates; 128-bit integers become strings.
96    ///
97    /// # Examples
98    ///
99    /// ```rust
100    /// use libmaxminddb_rs::ValueRef;
101    /// assert_eq!(ValueRef::Uint32(64512).to_json(), serde_json::json!(64512));
102    /// ```
103    pub fn to_json(&self) -> serde_json::Value {
104        match self {
105            Self::Utf8(v) => serde_json::Value::String((*v).to_owned()),
106            Self::Bytes(v) => {
107                serde_json::Value::Array(v.iter().map(|b| serde_json::Value::from(*b)).collect())
108            }
109            Self::Double(v) => serde_json::json!(v),
110            Self::Float(v) => serde_json::json!(v),
111            Self::Uint16(v) => serde_json::json!(v),
112            Self::Uint32(v) => serde_json::json!(v),
113            Self::Int32(v) => serde_json::json!(v),
114            Self::Uint64(v) => serde_json::json!(v),
115            Self::Uint128(v) => serde_json::Value::String(v.to_string()),
116            Self::Bool(v) => serde_json::json!(v),
117            Self::Array(values) => {
118                serde_json::Value::Array(values.iter().map(Self::to_json).collect())
119            }
120            Self::Map(entries) => serde_json::Value::Object(
121                entries
122                    .iter()
123                    .map(|(k, v)| ((*k).to_owned(), v.to_json()))
124                    .collect(),
125            ),
126        }
127    }
128}
129
130/// Owned representation used by the writer and deep-merge engine.
131#[derive(Debug, Clone, PartialEq)]
132pub enum Value {
133    /// Owned UTF-8 string.
134    Utf8(String),
135    /// Owned byte string.
136    Bytes(Vec<u8>),
137    /// IEEE-754 64-bit floating-point value.
138    Double(f64),
139    /// IEEE-754 32-bit floating-point value.
140    Float(f32),
141    /// Unsigned 16-bit integer.
142    Uint16(u16),
143    /// Unsigned 32-bit integer.
144    Uint32(u32),
145    /// Signed 32-bit integer.
146    Int32(i32),
147    /// Unsigned 64-bit integer.
148    Uint64(u64),
149    /// Unsigned 128-bit integer.
150    Uint128(u128),
151    /// Boolean value.
152    Bool(bool),
153    /// Owned MMDB array.
154    Array(Vec<Value>),
155    /// Owned MMDB map with deterministic key ordering.
156    Map(BTreeMap<String, Value>),
157}
158
159impl Value {
160    /// Converts any serde-serializable value into the writer's generic value model.
161    ///
162    /// Serialization walks the `serde` data model directly instead of building an
163    /// intermediate `serde_json::Value`, which roughly halves the per-record cost of
164    /// [`Writer::insert`](crate::Writer::insert). Bools, strings, byte strings,
165    /// sequences and maps keep their shape; integral numbers become `Uint64` or
166    /// `Int32`, floating point becomes `Double`, `None`/unit are rejected because
167    /// MMDB has no null type, and enum variants become maps.
168    ///
169    /// # Examples
170    ///
171    /// ```rust
172    /// use libmaxminddb_rs::Value;
173    /// let value = Value::from_serialize(&serde_json::json!({"asn": 64512}))?;
174    /// assert!(matches!(value, Value::Map(_)));
175    /// # Ok::<(), libmaxminddb_rs::Error>(())
176    /// ```
177    pub fn from_serialize<T: serde::Serialize + ?Sized>(value: &T) -> Result<Self> {
178        value.serialize(ValueSerializer)
179    }
180}
181
182fn null_error() -> Error {
183    Error::EncodingError("MMDB has no null data type".into())
184}
185
186/// Serializer producing [`Value`] without an intermediate JSON tree.
187struct ValueSerializer;
188
189/// Accumulates sequence-like values (`seq`, tuple, tuple struct).
190#[derive(Default)]
191struct SeqSerializer {
192    values: Vec<Value>,
193}
194
195/// Accumulates object-like values (map, struct).
196#[derive(Default)]
197struct MapSerializer {
198    entries: BTreeMap<String, Value>,
199    pending_key: Option<String>,
200}
201
202/// Accumulates the fields of a tuple enum variant.
203struct TupleVariantSerializer {
204    name: &'static str,
205    values: Vec<Value>,
206}
207
208/// Accumulates the fields of a struct enum variant.
209struct StructVariantSerializer {
210    name: &'static str,
211    entries: BTreeMap<String, Value>,
212}
213
214/// Accepts only string-like map keys, matching `serde_json`'s behavior.
215struct KeySerializer;
216
217impl serde::ser::Error for Error {
218    fn custom<T: std::fmt::Display>(message: T) -> Self {
219        Error::EncodingError(message.to_string())
220    }
221}
222
223impl ser::Serializer for ValueSerializer {
224    type Ok = Value;
225    type Error = Error;
226    type SerializeSeq = SeqSerializer;
227    type SerializeTuple = SeqSerializer;
228    type SerializeTupleStruct = SeqSerializer;
229    type SerializeTupleVariant = TupleVariantSerializer;
230    type SerializeMap = MapSerializer;
231    type SerializeStruct = MapSerializer;
232    type SerializeStructVariant = StructVariantSerializer;
233
234    fn serialize_bool(self, value: bool) -> Result<Self::Ok> {
235        Ok(Value::Bool(value))
236    }
237
238    fn serialize_i8(self, value: i8) -> Result<Self::Ok> {
239        Ok(Value::Int32(i32::from(value)))
240    }
241
242    fn serialize_i16(self, value: i16) -> Result<Self::Ok> {
243        Ok(Value::Int32(i32::from(value)))
244    }
245
246    fn serialize_i32(self, value: i32) -> Result<Self::Ok> {
247        Ok(Value::Int32(value))
248    }
249
250    fn serialize_i64(self, value: i64) -> Result<Self::Ok> {
251        i32::try_from(value)
252            .map(Value::Int32)
253            .map_err(|_| Error::EncodingError("signed JSON integer does not fit MMDB int32".into()))
254    }
255
256    fn serialize_i128(self, value: i128) -> Result<Self::Ok> {
257        if let Ok(unsigned) = u64::try_from(value) {
258            return Ok(Value::Uint64(unsigned));
259        }
260        i32::try_from(value)
261            .map(Value::Int32)
262            .map_err(|_| Error::EncodingError("signed JSON integer does not fit MMDB int32".into()))
263    }
264
265    fn serialize_u8(self, value: u8) -> Result<Self::Ok> {
266        Ok(Value::Uint64(u64::from(value)))
267    }
268
269    fn serialize_u16(self, value: u16) -> Result<Self::Ok> {
270        Ok(Value::Uint64(u64::from(value)))
271    }
272
273    fn serialize_u32(self, value: u32) -> Result<Self::Ok> {
274        Ok(Value::Uint64(u64::from(value)))
275    }
276
277    fn serialize_u64(self, value: u64) -> Result<Self::Ok> {
278        Ok(Value::Uint64(value))
279    }
280
281    fn serialize_u128(self, value: u128) -> Result<Self::Ok> {
282        u64::try_from(value).map(Value::Uint64).map_err(|_| {
283            Error::EncodingError("unsigned JSON integer does not fit MMDB uint64".into())
284        })
285    }
286
287    fn serialize_f32(self, value: f32) -> Result<Self::Ok> {
288        Ok(Value::Double(f64::from(value)))
289    }
290
291    fn serialize_f64(self, value: f64) -> Result<Self::Ok> {
292        Ok(Value::Double(value))
293    }
294
295    fn serialize_char(self, value: char) -> Result<Self::Ok> {
296        Ok(Value::Utf8(value.to_string()))
297    }
298
299    fn serialize_str(self, value: &str) -> Result<Self::Ok> {
300        Ok(Value::Utf8(value.to_owned()))
301    }
302
303    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> {
304        Ok(Value::Array(
305            value
306                .iter()
307                .map(|&byte| Value::Uint64(u64::from(byte)))
308                .collect(),
309        ))
310    }
311
312    fn serialize_none(self) -> Result<Self::Ok> {
313        Err(null_error())
314    }
315
316    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok> {
317        value.serialize(self)
318    }
319
320    fn serialize_unit(self) -> Result<Self::Ok> {
321        Err(null_error())
322    }
323
324    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
325        Err(null_error())
326    }
327
328    fn serialize_unit_variant(
329        self,
330        _name: &'static str,
331        _variant_index: u32,
332        variant: &'static str,
333    ) -> Result<Self::Ok> {
334        Ok(Value::Utf8(variant.to_owned()))
335    }
336
337    fn serialize_newtype_struct<T: ?Sized + Serialize>(
338        self,
339        _name: &'static str,
340        value: &T,
341    ) -> Result<Self::Ok> {
342        value.serialize(self)
343    }
344
345    fn serialize_newtype_variant<T: ?Sized + Serialize>(
346        self,
347        _name: &'static str,
348        _variant_index: u32,
349        variant: &'static str,
350        value: &T,
351    ) -> Result<Self::Ok> {
352        let mut entries = BTreeMap::new();
353        entries.insert(variant.to_owned(), value.serialize(ValueSerializer)?);
354        Ok(Value::Map(entries))
355    }
356
357    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
358        Ok(SeqSerializer {
359            values: Vec::with_capacity(len.unwrap_or(0)),
360        })
361    }
362
363    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
364        Ok(SeqSerializer {
365            values: Vec::with_capacity(len),
366        })
367    }
368
369    fn serialize_tuple_struct(
370        self,
371        _name: &'static str,
372        len: usize,
373    ) -> Result<Self::SerializeTupleStruct> {
374        Ok(SeqSerializer {
375            values: Vec::with_capacity(len),
376        })
377    }
378
379    fn serialize_tuple_variant(
380        self,
381        _name: &'static str,
382        _variant_index: u32,
383        variant: &'static str,
384        len: usize,
385    ) -> Result<Self::SerializeTupleVariant> {
386        Ok(TupleVariantSerializer {
387            name: variant,
388            values: Vec::with_capacity(len),
389        })
390    }
391
392    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
393        Ok(MapSerializer::default())
394    }
395
396    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
397        Ok(MapSerializer::default())
398    }
399
400    fn serialize_struct_variant(
401        self,
402        _name: &'static str,
403        _variant_index: u32,
404        variant: &'static str,
405        _len: usize,
406    ) -> Result<Self::SerializeStructVariant> {
407        Ok(StructVariantSerializer {
408            name: variant,
409            entries: BTreeMap::new(),
410        })
411    }
412}
413
414impl ser::SerializeSeq for SeqSerializer {
415    type Ok = Value;
416    type Error = Error;
417
418    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
419        self.values.push(value.serialize(ValueSerializer)?);
420        Ok(())
421    }
422
423    fn end(self) -> Result<Self::Ok> {
424        Ok(Value::Array(self.values))
425    }
426}
427
428impl ser::SerializeTuple for SeqSerializer {
429    type Ok = Value;
430    type Error = Error;
431
432    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
433        self.values.push(value.serialize(ValueSerializer)?);
434        Ok(())
435    }
436
437    fn end(self) -> Result<Self::Ok> {
438        Ok(Value::Array(self.values))
439    }
440}
441
442impl ser::SerializeTupleStruct for SeqSerializer {
443    type Ok = Value;
444    type Error = Error;
445
446    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
447        self.values.push(value.serialize(ValueSerializer)?);
448        Ok(())
449    }
450
451    fn end(self) -> Result<Self::Ok> {
452        Ok(Value::Array(self.values))
453    }
454}
455
456impl ser::SerializeTupleVariant for TupleVariantSerializer {
457    type Ok = Value;
458    type Error = Error;
459
460    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
461        self.values.push(value.serialize(ValueSerializer)?);
462        Ok(())
463    }
464
465    fn end(self) -> Result<Self::Ok> {
466        let mut entries = BTreeMap::new();
467        entries.insert(self.name.to_owned(), Value::Array(self.values));
468        Ok(Value::Map(entries))
469    }
470}
471
472impl ser::SerializeMap for MapSerializer {
473    type Ok = Value;
474    type Error = Error;
475
476    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
477        self.pending_key = Some(key.serialize(KeySerializer)?);
478        Ok(())
479    }
480
481    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
482        let key = self
483            .pending_key
484            .take()
485            .ok_or_else(|| Error::EncodingError("MMDB map value without a key".into()))?;
486        self.entries.insert(key, value.serialize(ValueSerializer)?);
487        Ok(())
488    }
489
490    fn end(self) -> Result<Self::Ok> {
491        Ok(Value::Map(self.entries))
492    }
493}
494
495impl ser::SerializeStruct for MapSerializer {
496    type Ok = Value;
497    type Error = Error;
498
499    fn serialize_field<T: ?Sized + Serialize>(
500        &mut self,
501        key: &'static str,
502        value: &T,
503    ) -> Result<()> {
504        self.entries
505            .insert(key.to_owned(), value.serialize(ValueSerializer)?);
506        Ok(())
507    }
508
509    fn end(self) -> Result<Self::Ok> {
510        Ok(Value::Map(self.entries))
511    }
512}
513
514impl ser::SerializeStructVariant for StructVariantSerializer {
515    type Ok = Value;
516    type Error = Error;
517
518    fn serialize_field<T: ?Sized + Serialize>(
519        &mut self,
520        key: &'static str,
521        value: &T,
522    ) -> Result<()> {
523        self.entries
524            .insert(key.to_owned(), value.serialize(ValueSerializer)?);
525        Ok(())
526    }
527
528    fn end(self) -> Result<Self::Ok> {
529        let mut entries = BTreeMap::new();
530        entries.insert(self.name.to_owned(), Value::Map(self.entries));
531        Ok(Value::Map(entries))
532    }
533}
534
535fn key_error() -> Error {
536    Error::EncodingError("MMDB map keys must be strings".into())
537}
538
539impl ser::Serializer for KeySerializer {
540    type Ok = String;
541    type Error = Error;
542    type SerializeSeq = Impossible<String, Error>;
543    type SerializeTuple = Impossible<String, Error>;
544    type SerializeTupleStruct = Impossible<String, Error>;
545    type SerializeTupleVariant = Impossible<String, Error>;
546    type SerializeMap = Impossible<String, Error>;
547    type SerializeStruct = Impossible<String, Error>;
548    type SerializeStructVariant = Impossible<String, Error>;
549
550    fn serialize_str(self, value: &str) -> Result<Self::Ok> {
551        Ok(value.to_owned())
552    }
553
554    fn collect_str<T: ?Sized + std::fmt::Display>(self, value: &T) -> Result<Self::Ok> {
555        Ok(value.to_string())
556    }
557
558    fn serialize_bool(self, _value: bool) -> Result<Self::Ok> {
559        Err(key_error())
560    }
561
562    fn serialize_i8(self, _value: i8) -> Result<Self::Ok> {
563        Err(key_error())
564    }
565
566    fn serialize_i16(self, _value: i16) -> Result<Self::Ok> {
567        Err(key_error())
568    }
569
570    fn serialize_i32(self, _value: i32) -> Result<Self::Ok> {
571        Err(key_error())
572    }
573
574    fn serialize_i64(self, _value: i64) -> Result<Self::Ok> {
575        Err(key_error())
576    }
577
578    fn serialize_i128(self, _value: i128) -> Result<Self::Ok> {
579        Err(key_error())
580    }
581
582    fn serialize_u8(self, _value: u8) -> Result<Self::Ok> {
583        Err(key_error())
584    }
585
586    fn serialize_u16(self, _value: u16) -> Result<Self::Ok> {
587        Err(key_error())
588    }
589
590    fn serialize_u32(self, _value: u32) -> Result<Self::Ok> {
591        Err(key_error())
592    }
593
594    fn serialize_u64(self, _value: u64) -> Result<Self::Ok> {
595        Err(key_error())
596    }
597
598    fn serialize_u128(self, _value: u128) -> Result<Self::Ok> {
599        Err(key_error())
600    }
601
602    fn serialize_f32(self, _value: f32) -> Result<Self::Ok> {
603        Err(key_error())
604    }
605
606    fn serialize_f64(self, _value: f64) -> Result<Self::Ok> {
607        Err(key_error())
608    }
609
610    fn serialize_char(self, _value: char) -> Result<Self::Ok> {
611        Err(key_error())
612    }
613
614    fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok> {
615        Err(key_error())
616    }
617
618    fn serialize_none(self) -> Result<Self::Ok> {
619        Err(key_error())
620    }
621
622    fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<Self::Ok> {
623        Err(key_error())
624    }
625
626    fn serialize_unit(self) -> Result<Self::Ok> {
627        Err(key_error())
628    }
629
630    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
631        Err(key_error())
632    }
633
634    fn serialize_unit_variant(
635        self,
636        _name: &'static str,
637        _variant_index: u32,
638        _variant: &'static str,
639    ) -> Result<Self::Ok> {
640        Err(key_error())
641    }
642
643    fn serialize_newtype_struct<T: ?Sized + Serialize>(
644        self,
645        _name: &'static str,
646        value: &T,
647    ) -> Result<Self::Ok> {
648        value.serialize(self)
649    }
650
651    fn serialize_newtype_variant<T: ?Sized + Serialize>(
652        self,
653        _name: &'static str,
654        _variant_index: u32,
655        _variant: &'static str,
656        _value: &T,
657    ) -> Result<Self::Ok> {
658        Err(key_error())
659    }
660
661    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
662        Err(key_error())
663    }
664
665    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
666        Err(key_error())
667    }
668
669    fn serialize_tuple_struct(
670        self,
671        _name: &'static str,
672        _len: usize,
673    ) -> Result<Self::SerializeTupleStruct> {
674        Err(key_error())
675    }
676
677    fn serialize_tuple_variant(
678        self,
679        _name: &'static str,
680        _variant_index: u32,
681        _variant: &'static str,
682        _len: usize,
683    ) -> Result<Self::SerializeTupleVariant> {
684        Err(key_error())
685    }
686
687    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
688        Err(key_error())
689    }
690
691    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
692        Err(key_error())
693    }
694
695    fn serialize_struct_variant(
696        self,
697        _name: &'static str,
698        _variant_index: u32,
699        _variant: &'static str,
700        _len: usize,
701    ) -> Result<Self::SerializeStructVariant> {
702        Err(key_error())
703    }
704}
705
706#[cfg(test)]
707mod serializer_tests {
708    use super::*;
709    use serde::Serialize;
710
711    #[derive(Serialize)]
712    struct Record {
713        name: String,
714        score: u32,
715        signed: i32,
716        nested: Vec<bool>,
717    }
718
719    #[derive(Serialize)]
720    enum Shape {
721        Unit,
722        Newtype(u32),
723        Tuple(u32, u32),
724        Struct { x: i32 },
725    }
726
727    fn map(entries: impl IntoIterator<Item = (&'static str, Value)>) -> Value {
728        Value::Map(
729            entries
730                .into_iter()
731                .map(|(k, v)| (k.to_owned(), v))
732                .collect(),
733        )
734    }
735
736    #[test]
737    fn serializes_struct_and_scalars() {
738        let value = Value::from_serialize(&Record {
739            name: "x".into(),
740            score: 7,
741            signed: -3,
742            nested: vec![true, false],
743        })
744        .unwrap();
745        assert_eq!(
746            value,
747            map([
748                ("name", Value::Utf8("x".into())),
749                ("score", Value::Uint64(7)),
750                ("signed", Value::Int32(-3)),
751                (
752                    "nested",
753                    Value::Array(vec![Value::Bool(true), Value::Bool(false)]),
754                ),
755            ])
756        );
757    }
758
759    #[test]
760    fn serializes_bytes_and_floats() {
761        assert_eq!(
762            Value::from_serialize(&serde_bytes::ByteBuf::from(vec![1u8, 2, 3])).unwrap(),
763            Value::Array(vec![Value::Uint64(1), Value::Uint64(2), Value::Uint64(3)])
764        );
765        assert_eq!(Value::from_serialize(&1.5f64).unwrap(), Value::Double(1.5));
766        assert_eq!(Value::from_serialize(&2.5f32).unwrap(), Value::Double(2.5));
767    }
768
769    #[test]
770    fn serializes_number_boundaries() {
771        assert_eq!(
772            Value::from_serialize(&i64::from(i32::MIN)).unwrap(),
773            Value::Int32(i32::MIN)
774        );
775        assert!(Value::from_serialize(&(i64::from(i32::MAX) + 1)).is_err());
776        assert_eq!(
777            Value::from_serialize(&u64::MAX).unwrap(),
778            Value::Uint64(u64::MAX)
779        );
780        assert_eq!(
781            Value::from_serialize(&(i128::from(i32::MAX) + 1)).unwrap(),
782            Value::Uint64(2_147_483_648)
783        );
784        assert!(Value::from_serialize(&i128::MIN).is_err());
785        assert_eq!(
786            Value::from_serialize(&u128::from(u64::MAX)).unwrap(),
787            Value::Uint64(u64::MAX)
788        );
789        assert!(Value::from_serialize(&(u128::from(u64::MAX) + 1)).is_err());
790    }
791
792    #[test]
793    fn narrow_signed_numbers_chars_and_tuples_keep_their_values() {
794        assert_eq!(Value::from_serialize(&(-5_i8)).unwrap(), Value::Int32(-5));
795        assert_eq!(
796            Value::from_serialize(&(-300_i16)).unwrap(),
797            Value::Int32(-300)
798        );
799        assert_eq!(
800            Value::from_serialize(&'é').unwrap(),
801            Value::Utf8("é".into())
802        );
803        assert_eq!(
804            Value::from_serialize(&(1_u32, 2_u32)).unwrap(),
805            Value::Array(vec![Value::Uint64(1), Value::Uint64(2)])
806        );
807    }
808
809    #[test]
810    fn rejects_null_and_non_string_keys() {
811        assert!(Value::from_serialize(&Option::<u32>::None).is_err());
812        assert!(Value::from_serialize(&()).is_err());
813        let mut keyed = BTreeMap::new();
814        keyed.insert(1u32, 2u32);
815        assert!(Value::from_serialize(&keyed).is_err());
816        assert_eq!(
817            Value::from_serialize(&Some(5u32)).unwrap(),
818            Value::Uint64(5)
819        );
820    }
821
822    fn sample_value_ref() -> Vec<ValueRef<'static>> {
823        vec![
824            ValueRef::Utf8("s"),
825            ValueRef::Bytes(&[1, 2]),
826            ValueRef::Double(1.5),
827            ValueRef::Float(2.5),
828            ValueRef::Uint16(16),
829            ValueRef::Uint32(32),
830            ValueRef::Int32(-3),
831            ValueRef::Uint64(64),
832            ValueRef::Uint128(u128::MAX),
833            ValueRef::Bool(true),
834            ValueRef::Array(vec![ValueRef::Uint64(1)]),
835            ValueRef::Map(vec![("k", ValueRef::Int32(7))]),
836        ]
837    }
838
839    #[test]
840    fn value_ref_to_owned_value_covers_all_variants() {
841        let owned: Vec<Value> = sample_value_ref()
842            .iter()
843            .map(ValueRef::to_owned_value)
844            .collect();
845        assert_eq!(
846            owned,
847            vec![
848                Value::Utf8("s".into()),
849                Value::Bytes(vec![1, 2]),
850                Value::Double(1.5),
851                Value::Float(2.5),
852                Value::Uint16(16),
853                Value::Uint32(32),
854                Value::Int32(-3),
855                Value::Uint64(64),
856                Value::Uint128(u128::MAX),
857                Value::Bool(true),
858                Value::Array(vec![Value::Uint64(1)]),
859                Value::Map([("k".to_owned(), Value::Int32(7))].into()),
860            ]
861        );
862    }
863
864    #[test]
865    fn value_ref_to_json_covers_all_variants() {
866        let json: Vec<serde_json::Value> =
867            sample_value_ref().iter().map(ValueRef::to_json).collect();
868        assert_eq!(
869            json,
870            vec![
871                serde_json::json!("s"),
872                serde_json::json!([1, 2]),
873                serde_json::json!(1.5),
874                serde_json::json!(2.5),
875                serde_json::json!(16),
876                serde_json::json!(32),
877                serde_json::json!(-3),
878                serde_json::json!(64),
879                serde_json::json!(u128::MAX.to_string()),
880                serde_json::json!(true),
881                serde_json::json!([1]),
882                serde_json::json!({"k": 7}),
883            ]
884        );
885    }
886
887    #[test]
888    fn value_ref_get_requires_a_map() {
889        let map = ValueRef::Map(vec![("k", ValueRef::Uint16(1))]);
890        assert_eq!(map.get("k"), Some(&ValueRef::Uint16(1)));
891        assert_eq!(map.get("missing"), None);
892        assert_eq!(ValueRef::Uint64(1).get("k"), None);
893    }
894
895    #[test]
896    fn serde_error_custom_builds_encoding_error() {
897        let error: Error = <Error as serde::ser::Error>::custom("boom");
898        let message = error.to_string();
899        assert!(message.contains("boom"));
900    }
901
902    #[derive(Serialize)]
903    struct Newtype(u64);
904
905    #[derive(Serialize)]
906    struct Tuple(u8, u16);
907
908    #[test]
909    fn serializes_newtype_and_tuple_struct_and_unit_struct() {
910        assert_eq!(
911            Value::from_serialize(&Newtype(9)).unwrap(),
912            Value::Uint64(9)
913        );
914        assert_eq!(
915            Value::from_serialize(&Tuple(1, 2)).unwrap(),
916            Value::Array(vec![Value::Uint64(1), Value::Uint64(2)])
917        );
918        // A unit struct maps to the undefined null type and is rejected.
919        #[derive(Serialize)]
920        struct Unit;
921        assert!(Value::from_serialize(&Unit).is_err());
922    }
923
924    #[test]
925    fn key_serializer_accepts_strings_and_collect_str() {
926        use serde::ser::Serializer;
927        assert_eq!(
928            KeySerializer.serialize_str("abc").unwrap(),
929            "abc".to_owned()
930        );
931        assert_eq!(KeySerializer.collect_str(&7_u64).unwrap(), "7".to_owned());
932    }
933
934    #[test]
935    fn key_serializer_rejects_non_string_keys() {
936        use serde::ser::Serializer;
937        macro_rules! reject {
938            ($call:expr) => {
939                assert!(matches!($call, Result::Err(_)), "expected key error")
940            };
941        }
942        reject!(KeySerializer.serialize_bool(true));
943        reject!(KeySerializer.serialize_i8(1));
944        reject!(KeySerializer.serialize_i16(1));
945        reject!(KeySerializer.serialize_i32(1));
946        reject!(KeySerializer.serialize_i64(1));
947        reject!(KeySerializer.serialize_i128(1));
948        reject!(KeySerializer.serialize_u8(1));
949        reject!(KeySerializer.serialize_u16(1));
950        reject!(KeySerializer.serialize_u64(1));
951        reject!(KeySerializer.serialize_u128(1));
952        reject!(KeySerializer.serialize_f32(1.0));
953        reject!(KeySerializer.serialize_f64(1.0));
954        reject!(KeySerializer.serialize_char('x'));
955        reject!(KeySerializer.serialize_bytes(&[1]));
956        reject!(KeySerializer.serialize_none());
957        reject!(KeySerializer.serialize_some(&1_u32));
958        reject!(KeySerializer.serialize_unit());
959        reject!(KeySerializer.serialize_unit_struct("U"));
960        reject!(KeySerializer.serialize_unit_variant("E", 0, "V"));
961        reject!(KeySerializer.serialize_newtype_variant("E", 0, "V", &1_u32));
962        reject!(KeySerializer.serialize_seq(None));
963        reject!(KeySerializer.serialize_tuple(1));
964        reject!(KeySerializer.serialize_tuple_struct("T", 1));
965        reject!(KeySerializer.serialize_tuple_variant("E", 0, "V", 1));
966        reject!(KeySerializer.serialize_map(None));
967        reject!(KeySerializer.serialize_struct("S", 1));
968        reject!(KeySerializer.serialize_struct_variant("E", 0, "V", 1));
969        let message = KeySerializer.serialize_bool(true).unwrap_err();
970        assert!(matches!(
971            message,
972            crate::Error::EncodingError(msg) if msg.contains("strings")
973        ));
974    }
975
976    #[test]
977    fn serializes_enum_variants() {
978        assert_eq!(
979            Value::from_serialize(&Shape::Unit).unwrap(),
980            Value::Utf8("Unit".into())
981        );
982        assert_eq!(
983            Value::from_serialize(&Shape::Newtype(1)).unwrap(),
984            map([("Newtype", Value::Uint64(1))])
985        );
986        assert_eq!(
987            Value::from_serialize(&Shape::Tuple(1, 2)).unwrap(),
988            map([(
989                "Tuple",
990                Value::Array(vec![Value::Uint64(1), Value::Uint64(2)])
991            )])
992        );
993        assert_eq!(
994            Value::from_serialize(&Shape::Struct { x: -1 }).unwrap(),
995            map([("Struct", map([("x", Value::Int32(-1))]))])
996        );
997    }
998}