Skip to main content

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