messagepack_serde/value/
value_ref.rs

1use super::number::Number;
2use alloc::vec::Vec;
3use messagepack_core::extension::ExtensionRef;
4use serde::{de::Visitor, ser::SerializeMap};
5
6/// Represents any messagepack value. `alloc` needed.
7#[derive(Debug, Clone, PartialEq, PartialOrd)]
8pub enum ValueRef<'a> {
9    /// Represents nil format
10    Nil,
11    /// Represents bool format family
12    Bool(bool),
13    /// Represents `bin 8`, `bin 16` and `bin 32`
14    Bin(&'a [u8]),
15    /// Represents ext format family
16    Extension(ExtensionRef<'a>),
17    /// Represents int format family and float format family
18    Number(Number),
19    /// Represents str format family
20    String(&'a str),
21    /// Represents array format family
22    Array(Vec<ValueRef<'a>>),
23    /// Represents map format family
24    Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
25}
26
27impl ValueRef<'_> {
28    /// Returns true if the `ValueRef` is nil
29    pub fn is_nil(&self) -> bool {
30        matches!(self, ValueRef::Nil)
31    }
32
33    /// If the `ValueRef` is boolean, returns contained value.
34    pub fn as_bool(&self) -> Option<bool> {
35        match self {
36            ValueRef::Bool(v) => Some(*v),
37            _ => None,
38        }
39    }
40
41    /// If the `ValueRef` is bin, returns contained value.
42    pub fn as_bin(&self) -> Option<&[u8]> {
43        match self {
44            ValueRef::Bin(v) => Some(*v),
45            _ => None,
46        }
47    }
48
49    /// If the `ValueRef` is ext, returns contained value.
50    pub fn as_extension(&self) -> Option<&ExtensionRef<'_>> {
51        match self {
52            ValueRef::Extension(v) => Some(v),
53            _ => None,
54        }
55    }
56
57    /// If the `ValueRef` is number, returns contained value.
58    pub fn as_number(&self) -> Option<Number> {
59        match self {
60            ValueRef::Number(v) => Some(*v),
61            _ => None,
62        }
63    }
64
65    /// If the `ValueRef` is str, returns contained value.
66    pub fn as_string(&self) -> Option<&str> {
67        match self {
68            ValueRef::String(v) => Some(*v),
69            _ => None,
70        }
71    }
72
73    /// If the `ValueRef` is array, returns contained value.
74    pub fn as_array(&self) -> Option<&[ValueRef<'_>]> {
75        match self {
76            ValueRef::Array(v) => Some(v),
77            _ => None,
78        }
79    }
80
81    /// If the `ValueRef` is map, returns contained value.
82    pub fn as_map(&self) -> Option<&[(ValueRef<'_>, ValueRef<'_>)]> {
83        match self {
84            ValueRef::Map(v) => Some(v),
85            _ => None,
86        }
87    }
88}
89
90impl serde::Serialize for ValueRef<'_> {
91    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92    where
93        S: serde::Serializer,
94    {
95        match self {
96            ValueRef::Nil => serializer.serialize_none(),
97            ValueRef::Bool(v) => serializer.serialize_bool(*v),
98            ValueRef::Bin(items) => serializer.serialize_bytes(items),
99            ValueRef::Extension(extension_ref) => {
100                super::ext_ref::serialize(extension_ref, serializer)
101            }
102            ValueRef::Number(number) => number.serialize(serializer),
103            ValueRef::String(s) => serializer.serialize_str(s),
104            ValueRef::Array(value_refs) => (*value_refs).serialize(serializer),
105            ValueRef::Map(items) => {
106                let mut map = serializer.serialize_map(Some(items.len()))?;
107                for (k, v) in items.iter() {
108                    map.serialize_entry(k, v)?;
109                }
110                map.end()
111            }
112        }
113    }
114}
115
116impl<'de> serde::Deserialize<'de> for ValueRef<'de> {
117    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118    where
119        D: serde::Deserializer<'de>,
120    {
121        struct ValueVisitor;
122        impl<'de> Visitor<'de> for ValueVisitor {
123            type Value = ValueRef<'de>;
124            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
125                formatter.write_str("expect valid messagepack")
126            }
127
128            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
129            where
130                E: serde::de::Error,
131            {
132                Ok(ValueRef::Bool(v))
133            }
134
135            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
136            where
137                E: serde::de::Error,
138            {
139                let n = Number::from(v);
140                Ok(ValueRef::Number(n))
141            }
142
143            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
144            where
145                E: serde::de::Error,
146            {
147                let n = Number::from(v);
148                Ok(ValueRef::Number(n))
149            }
150
151            fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
152            where
153                E: serde::de::Error,
154            {
155                let n = Number::from(v);
156                Ok(ValueRef::from(n))
157            }
158
159            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
160            where
161                E: serde::de::Error,
162            {
163                let n = Number::from(v);
164                Ok(ValueRef::from(n))
165            }
166
167            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
168            where
169                E: serde::de::Error,
170            {
171                Ok(ValueRef::String(v))
172            }
173
174            fn visit_none<E>(self) -> Result<Self::Value, E>
175            where
176                E: serde::de::Error,
177            {
178                Ok(ValueRef::Nil)
179            }
180
181            fn visit_unit<E>(self) -> Result<Self::Value, E>
182            where
183                E: serde::de::Error,
184            {
185                Ok(ValueRef::Nil)
186            }
187
188            fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
189            where
190                E: serde::de::Error,
191            {
192                Ok(ValueRef::Bin(v))
193            }
194
195            fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
196            where
197                D: serde::Deserializer<'de>,
198            {
199                let ext = super::ext_ref::deserialize(deserializer)?;
200                Ok(ValueRef::Extension(ext))
201            }
202
203            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
204            where
205                A: serde::de::SeqAccess<'de>,
206            {
207                let mut buf = Vec::new();
208                if let Some(size) = seq.size_hint() {
209                    buf.reserve(size);
210                }
211
212                while let Some(v) = seq.next_element::<ValueRef>()? {
213                    buf.push(v);
214                }
215
216                Ok(ValueRef::Array(buf))
217            }
218
219            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
220            where
221                A: serde::de::MapAccess<'de>,
222            {
223                let mut buf = Vec::new();
224                if let Some(size) = map.size_hint() {
225                    buf.reserve(size);
226                }
227
228                while let Some(v) = map.next_entry()? {
229                    buf.push(v);
230                }
231
232                Ok(ValueRef::Map(buf))
233            }
234        }
235        deserializer.deserialize_any(ValueVisitor)
236    }
237}
238
239impl From<()> for ValueRef<'_> {
240    fn from(_: ()) -> Self {
241        ValueRef::Nil
242    }
243}
244
245impl From<bool> for ValueRef<'_> {
246    fn from(v: bool) -> Self {
247        ValueRef::Bool(v)
248    }
249}
250
251impl From<u8> for ValueRef<'_> {
252    fn from(v: u8) -> Self {
253        ValueRef::Number(Number::from(v))
254    }
255}
256
257impl From<u16> for ValueRef<'_> {
258    fn from(v: u16) -> Self {
259        ValueRef::Number(Number::from(v))
260    }
261}
262
263impl From<u32> for ValueRef<'_> {
264    fn from(v: u32) -> Self {
265        ValueRef::Number(Number::from(v))
266    }
267}
268
269impl From<u64> for ValueRef<'_> {
270    fn from(v: u64) -> Self {
271        ValueRef::Number(Number::from(v))
272    }
273}
274
275impl From<i8> for ValueRef<'_> {
276    fn from(v: i8) -> Self {
277        ValueRef::Number(Number::from(v))
278    }
279}
280
281impl From<i16> for ValueRef<'_> {
282    fn from(v: i16) -> Self {
283        ValueRef::Number(Number::from(v))
284    }
285}
286
287impl From<i32> for ValueRef<'_> {
288    fn from(v: i32) -> Self {
289        ValueRef::Number(Number::from(v))
290    }
291}
292
293impl From<i64> for ValueRef<'_> {
294    fn from(v: i64) -> Self {
295        ValueRef::Number(Number::from(v))
296    }
297}
298
299impl From<f32> for ValueRef<'_> {
300    fn from(v: f32) -> Self {
301        ValueRef::Number(Number::from(v))
302    }
303}
304
305impl From<f64> for ValueRef<'_> {
306    fn from(v: f64) -> Self {
307        ValueRef::Number(Number::from(v))
308    }
309}
310
311impl From<Number> for ValueRef<'_> {
312    fn from(v: Number) -> Self {
313        ValueRef::Number(v)
314    }
315}
316
317impl TryFrom<usize> for ValueRef<'_> {
318    type Error = core::num::TryFromIntError;
319    fn try_from(v: usize) -> Result<Self, Self::Error> {
320        Number::try_from(v).map(Self::from)
321    }
322}
323
324impl TryFrom<isize> for ValueRef<'_> {
325    type Error = core::num::TryFromIntError;
326    fn try_from(v: isize) -> Result<Self, Self::Error> {
327        Number::try_from(v).map(Self::from)
328    }
329}
330
331impl<'a> From<&'a str> for ValueRef<'a> {
332    fn from(v: &'a str) -> Self {
333        ValueRef::String(v)
334    }
335}
336
337impl<'a> From<&'a [u8]> for ValueRef<'a> {
338    fn from(v: &'a [u8]) -> Self {
339        ValueRef::Bin(v)
340    }
341}
342impl<'a> From<ExtensionRef<'a>> for ValueRef<'a> {
343    fn from(v: ExtensionRef<'a>) -> Self {
344        ValueRef::Extension(v)
345    }
346}
347
348#[cfg(test)]
349mod tests {
350    use super::*;
351    use crate::{from_slice, to_slice};
352    use messagepack_core::extension::ExtensionRef;
353    use rstest::rstest;
354
355    // Verify serialization of ValueRef scalars and simple composites using rstest.
356    #[rstest]
357    #[case(ValueRef::Nil, vec![0xc0])]
358    #[case(ValueRef::Bool(true), vec![0xc3])]
359    #[case(ValueRef::Number(Number::PositiveInt(5)), vec![0x05])]
360    // -33 encoded as int8: 0xd0, 0xdf
361    #[case(ValueRef::Number(Number::NegativeInt(-33)), vec![0xd0, 0xdf])]
362    // 1.5 can be represented as f32 => 0xca 3f c0 00 00
363    #[case(ValueRef::Number(Number::Float(1.5)), vec![0xca, 0x3f, 0xc0, 0x00, 0x00])]
364    #[case(ValueRef::String("a"), vec![0xa1, b'a'])]
365    // Bin encodes as MessagePack bin8 here
366    #[case(ValueRef::Bin(&[0x01, 0x02]), vec![0xc4, 0x02, 0x01, 0x02])]
367    #[case(
368        ValueRef::Array(vec![ValueRef::Bool(true), ValueRef::Nil]),
369        vec![0x92, 0xc3, 0xc0]
370    )]
371    #[case(
372        ValueRef::Map(vec![
373            (ValueRef::String("a"), ValueRef::Number(Number::NegativeInt(-1)))
374        ]),
375        vec![0x81, 0xa1, b'a', 0xff]
376    )]
377    fn encode_value_ref_cases(#[case] v: ValueRef<'_>, #[case] expected: Vec<u8>) {
378        let mut buf = vec![0u8; expected.len() + 8];
379        let len = to_slice(&v, &mut buf).unwrap();
380        assert_eq!(buf[..len], expected);
381    }
382
383    // Verify deserialization of ValueRef scalars and simple composites.
384    #[rstest]
385    #[case(&[0xc0], ValueRef::Nil)]
386    #[case(&[0xc3], ValueRef::Bool(true))]
387    #[case(&[0x05], ValueRef::Number(Number::PositiveInt(5)))]
388    #[case(&[0xd0, 0xdf], ValueRef::Number(Number::NegativeInt(-33)))]
389    #[case(&[0xca, 0x3f, 0xc0, 0x00, 0x00], ValueRef::Number(Number::Float(1.5)))]
390    #[case(&[0xa1, b'a'], ValueRef::String("a"))]
391    #[case(&[0xc4, 0x02, 0x01, 0x02], ValueRef::Bin(&[0x01, 0x02]))]
392    #[case(&[0x92, 0xc3, 0xc0], ValueRef::Array(vec![ValueRef::Bool(true), ValueRef::Nil]))]
393    #[case(
394        &[0x81, 0xa1, b'a', 0xff],
395        ValueRef::Map(vec![
396            (ValueRef::String("a"), ValueRef::Number(Number::NegativeInt(-1)))
397        ])
398    )]
399    fn decode_value_ref_cases(#[case] input: &[u8], #[case] expected: ValueRef<'_>) {
400        let v = from_slice::<ValueRef<'_>>(input).unwrap();
401        assert_eq!(v, expected);
402    }
403
404    // Verify extension encoding/decoding via ValueRef::Extension.
405    #[test]
406    fn encode_value_ref_extension_fixext1() {
407        let kind: i8 = 10;
408        let v = ValueRef::Extension(ExtensionRef::new(kind, &[0x12]));
409        let mut buf = [0u8; 3];
410        let len = to_slice(&v, &mut buf).unwrap();
411        assert_eq!(len, 3);
412        assert_eq!(buf, [0xd4, kind as u8, 0x12]);
413    }
414
415    // Round-trip timestamp 32 (ext type -1, 4-byte seconds field).
416    #[test]
417    fn decode_then_reencode_value_ref_extension_timestamp32_roundtrip() {
418        let ts32: &[u8] = &[0xd6, 0xff, 0x00, 0x00, 0x00, 0x00];
419        let v = from_slice::<ValueRef<'_>>(ts32).unwrap();
420        match v {
421            ValueRef::Extension(ext) => {
422                assert_eq!(ext.r#type, -1);
423                assert_eq!(ext.data, &[0x00, 0x00, 0x00, 0x00]);
424
425                // Re-encode and compare with original bytes
426                let mut buf = [0u8; 6];
427                let len = to_slice(&ValueRef::Extension(ext), &mut buf).unwrap();
428                assert_eq!(&buf[..len], ts32);
429            }
430            _ => panic!("expected extension"),
431        }
432    }
433
434    // {
435    //   "meta": {
436    //     "id": 1001,
437    //     "tags": ["sample", null, 42, {"extra": "yes"}]
438    //   },
439    //   "users": [
440    //     {
441    //       "name": "Alice",
442    //       "attributes": {
443    //         "age": 29,
444    //         "preferences": [
445    //           "coffee",
446    //           null,
447    //           {"music": ["jazz", "rock", {"genres": ["classical", 123]}]}
448    //         ]
449    //       }
450    //     },
451    //     {
452    //       "name": "Bob",
453    //       "attributes": {
454    //         "age": null,
455    //         "preferences": [
456    //           {"food": ["pizza", "sushi", null]},
457    //           [true, false, {"nested": [0, {"inner": "value"}]}]
458    //         ]
459    //       }
460    //     }
461    //   ]
462    // }
463    const COMPLEX: &[u8] = &[
464        0x82, 0xa4, 0x6d, 0x65, 0x74, 0x61, 0x82, 0xa2, 0x69, 0x64, 0xcd, 0x03, 0xe9, 0xa4, 0x74,
465        0x61, 0x67, 0x73, 0x94, 0xa6, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0xc0, 0x2a, 0x81, 0xa5,
466        0x65, 0x78, 0x74, 0x72, 0x61, 0xa3, 0x79, 0x65, 0x73, 0xa5, 0x75, 0x73, 0x65, 0x72, 0x73,
467        0x92, 0x82, 0xa4, 0x6e, 0x61, 0x6d, 0x65, 0xa5, 0x41, 0x6c, 0x69, 0x63, 0x65, 0xaa, 0x61,
468        0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x82, 0xa3, 0x61, 0x67, 0x65, 0x1d,
469        0xab, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x93, 0xa6, 0x63,
470        0x6f, 0x66, 0x66, 0x65, 0x65, 0xc0, 0x81, 0xa5, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x93, 0xa4,
471        0x6a, 0x61, 0x7a, 0x7a, 0xa4, 0x72, 0x6f, 0x63, 0x6b, 0x81, 0xa6, 0x67, 0x65, 0x6e, 0x72,
472        0x65, 0x73, 0x92, 0xa9, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x7b, 0x82,
473        0xa4, 0x6e, 0x61, 0x6d, 0x65, 0xa3, 0x42, 0x6f, 0x62, 0xaa, 0x61, 0x74, 0x74, 0x72, 0x69,
474        0x62, 0x75, 0x74, 0x65, 0x73, 0x82, 0xa3, 0x61, 0x67, 0x65, 0xc0, 0xab, 0x70, 0x72, 0x65,
475        0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x92, 0x81, 0xa4, 0x66, 0x6f, 0x6f, 0x64,
476        0x93, 0xa5, 0x70, 0x69, 0x7a, 0x7a, 0x61, 0xa5, 0x73, 0x75, 0x73, 0x68, 0x69, 0xc0, 0x93,
477        0xc3, 0xc2, 0x81, 0xa6, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x92, 0x00, 0x81, 0xa5, 0x69,
478        0x6e, 0x6e, 0x65, 0x72, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65,
479    ];
480    #[test]
481    fn roundtrip_complex() {
482        let meta = ValueRef::Map(vec![
483            (ValueRef::String("id"), ValueRef::from(1001)),
484            (
485                ValueRef::String("tags"),
486                ValueRef::Array(vec![
487                    ValueRef::String("sample"),
488                    ValueRef::Nil,
489                    ValueRef::from(42),
490                    ValueRef::Map(vec![(ValueRef::String("extra"), ValueRef::String("yes"))]),
491                ]),
492            ),
493        ]);
494        let alice = ValueRef::Map(vec![
495            (ValueRef::String("name"), ValueRef::String("Alice")),
496            (
497                ValueRef::String("attributes"),
498                ValueRef::Map(vec![
499                    (ValueRef::String("age"), ValueRef::from(29)),
500                    (
501                        ValueRef::String("preferences"),
502                        ValueRef::Array(vec![
503                            ValueRef::String("coffee"),
504                            ValueRef::Nil,
505                            ValueRef::Map(vec![(
506                                ValueRef::String("music"),
507                                ValueRef::Array(vec![
508                                    ValueRef::String("jazz"),
509                                    ValueRef::String("rock"),
510                                    ValueRef::Map(vec![(
511                                        ValueRef::String("genres"),
512                                        ValueRef::Array(vec![
513                                            ValueRef::String("classical"),
514                                            ValueRef::from(123),
515                                        ]),
516                                    )]),
517                                ]),
518                            )]),
519                        ]),
520                    ),
521                ]),
522            ),
523        ]);
524        let bob = ValueRef::Map(vec![
525            (ValueRef::String("name"), ValueRef::String("Bob")),
526            (
527                ValueRef::String("attributes"),
528                ValueRef::Map(vec![
529                    (ValueRef::String("age"), ValueRef::Nil),
530                    (
531                        ValueRef::String("preferences"),
532                        ValueRef::Array(vec![
533                            ValueRef::Map(vec![(
534                                ValueRef::String("food"),
535                                ValueRef::Array(vec![
536                                    ValueRef::String("pizza"),
537                                    ValueRef::String("sushi"),
538                                    ValueRef::Nil,
539                                ]),
540                            )]),
541                            ValueRef::Array(vec![
542                                ValueRef::Bool(true),
543                                ValueRef::Bool(false),
544                                ValueRef::Map(vec![(
545                                    ValueRef::String("nested"),
546                                    ValueRef::Array(vec![
547                                        ValueRef::from(0),
548                                        ValueRef::Map(vec![(
549                                            ValueRef::String("inner"),
550                                            ValueRef::String("value"),
551                                        )]),
552                                    ]),
553                                )]),
554                            ]),
555                        ]),
556                    ),
557                ]),
558            ),
559        ]);
560        let v = ValueRef::Map(vec![
561            (ValueRef::String("meta"), meta),
562            (ValueRef::String("users"), ValueRef::Array(vec![alice, bob])),
563        ]);
564
565        let deserialized = from_slice::<ValueRef<'_>>(COMPLEX).unwrap();
566        assert_eq!(deserialized, v);
567
568        let mut buf = [0u8; COMPLEX.len()];
569        let len = to_slice(&v, &mut buf).unwrap();
570        assert_eq!(len, COMPLEX.len());
571        assert_eq!(&buf, COMPLEX);
572    }
573}