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 = Vec::new();
212                if let Some(size) = seq.size_hint() {
213                    buf.reserve(size);
214                }
215
216                while let Some(v) = seq.next_element::<ValueRef>()? {
217                    buf.push(v);
218                }
219
220                Ok(ValueRef::Array(buf))
221            }
222
223            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
224            where
225                A: serde::de::MapAccess<'de>,
226            {
227                let mut buf = Vec::new();
228                if let Some(size) = map.size_hint() {
229                    buf.reserve(size);
230                }
231
232                while let Some(v) = map.next_entry()? {
233                    buf.push(v);
234                }
235
236                Ok(ValueRef::Map(buf))
237            }
238        }
239        deserializer.deserialize_any(ValueVisitor)
240    }
241}
242
243impl From<()> for ValueRef<'_> {
244    fn from(_: ()) -> Self {
245        ValueRef::Nil
246    }
247}
248
249impl From<bool> for ValueRef<'_> {
250    fn from(v: bool) -> Self {
251        ValueRef::Bool(v)
252    }
253}
254
255impl From<u8> for ValueRef<'_> {
256    fn from(v: u8) -> Self {
257        ValueRef::Number(Number::from(v))
258    }
259}
260
261impl From<u16> for ValueRef<'_> {
262    fn from(v: u16) -> Self {
263        ValueRef::Number(Number::from(v))
264    }
265}
266
267impl From<u32> for ValueRef<'_> {
268    fn from(v: u32) -> Self {
269        ValueRef::Number(Number::from(v))
270    }
271}
272
273impl From<u64> for ValueRef<'_> {
274    fn from(v: u64) -> Self {
275        ValueRef::Number(Number::from(v))
276    }
277}
278
279impl From<i8> for ValueRef<'_> {
280    fn from(v: i8) -> Self {
281        ValueRef::Number(Number::from(v))
282    }
283}
284
285impl From<i16> for ValueRef<'_> {
286    fn from(v: i16) -> Self {
287        ValueRef::Number(Number::from(v))
288    }
289}
290
291impl From<i32> for ValueRef<'_> {
292    fn from(v: i32) -> Self {
293        ValueRef::Number(Number::from(v))
294    }
295}
296
297impl From<i64> for ValueRef<'_> {
298    fn from(v: i64) -> Self {
299        ValueRef::Number(Number::from(v))
300    }
301}
302
303impl From<f32> for ValueRef<'_> {
304    fn from(v: f32) -> Self {
305        ValueRef::Number(Number::from(v))
306    }
307}
308
309impl From<f64> for ValueRef<'_> {
310    fn from(v: f64) -> Self {
311        ValueRef::Number(Number::from(v))
312    }
313}
314
315impl From<Number> for ValueRef<'_> {
316    fn from(v: Number) -> Self {
317        ValueRef::Number(v)
318    }
319}
320
321impl TryFrom<usize> for ValueRef<'_> {
322    type Error = core::num::TryFromIntError;
323    fn try_from(v: usize) -> Result<Self, Self::Error> {
324        Number::try_from(v).map(Self::from)
325    }
326}
327
328impl TryFrom<isize> for ValueRef<'_> {
329    type Error = core::num::TryFromIntError;
330    fn try_from(v: isize) -> Result<Self, Self::Error> {
331        Number::try_from(v).map(Self::from)
332    }
333}
334
335impl<'a> From<&'a str> for ValueRef<'a> {
336    fn from(v: &'a str) -> Self {
337        ValueRef::String(v)
338    }
339}
340
341impl<'a> From<&'a [u8]> for ValueRef<'a> {
342    fn from(v: &'a [u8]) -> Self {
343        ValueRef::Bin(v)
344    }
345}
346impl<'a> From<ExtensionRef<'a>> for ValueRef<'a> {
347    fn from(v: ExtensionRef<'a>) -> Self {
348        ValueRef::Extension(v)
349    }
350}
351
352#[cfg(test)]
353mod tests {
354    use super::*;
355    use crate::{from_slice, to_slice};
356    use messagepack_core::extension::ExtensionRef;
357    use rstest::rstest;
358
359    // Verify serialization of ValueRef scalars and simple composites using rstest.
360    #[rstest]
361    #[case(ValueRef::Nil, vec![0xc0])]
362    #[case(ValueRef::Bool(true), vec![0xc3])]
363    #[case(ValueRef::Number(Number::PositiveInt(5)), vec![0x05])]
364    // -33 encoded as int8: 0xd0, 0xdf
365    #[case(ValueRef::Number(Number::NegativeInt(-33)), vec![0xd0, 0xdf])]
366    // 1.5 can be represented as f32 => 0xca 3f c0 00 00
367    #[case(ValueRef::Number(Number::Float(1.5)), vec![0xca, 0x3f, 0xc0, 0x00, 0x00])]
368    #[case(ValueRef::String("a"), vec![0xa1, b'a'])]
369    // Bin encodes as MessagePack bin8 here
370    #[case(ValueRef::Bin(&[0x01, 0x02]), vec![0xc4, 0x02, 0x01, 0x02])]
371    #[case(
372        ValueRef::Array(vec![ValueRef::Bool(true), ValueRef::Nil]),
373        vec![0x92, 0xc3, 0xc0]
374    )]
375    #[case(
376        ValueRef::Map(vec![
377            (ValueRef::String("a"), ValueRef::Number(Number::NegativeInt(-1)))
378        ]),
379        vec![0x81, 0xa1, b'a', 0xff]
380    )]
381    fn encode_value_ref_cases(#[case] v: ValueRef<'_>, #[case] expected: Vec<u8>) {
382        let mut buf = vec![0u8; expected.len() + 8];
383        let len = to_slice(&v, &mut buf).unwrap();
384        assert_eq!(buf[..len], expected);
385    }
386
387    // Verify deserialization of ValueRef scalars and simple composites.
388    #[rstest]
389    #[case(&[0xc0], ValueRef::Nil)]
390    #[case(&[0xc3], ValueRef::Bool(true))]
391    #[case(&[0x05], ValueRef::Number(Number::PositiveInt(5)))]
392    #[case(&[0xd0, 0xdf], ValueRef::Number(Number::NegativeInt(-33)))]
393    #[case(&[0xca, 0x3f, 0xc0, 0x00, 0x00], ValueRef::Number(Number::Float(1.5)))]
394    #[case(&[0xa1, b'a'], ValueRef::String("a"))]
395    #[case(&[0xc4, 0x02, 0x01, 0x02], ValueRef::Bin(&[0x01, 0x02]))]
396    #[case(&[0x92, 0xc3, 0xc0], ValueRef::Array(vec![ValueRef::Bool(true), ValueRef::Nil]))]
397    #[case(
398        &[0x81, 0xa1, b'a', 0xff],
399        ValueRef::Map(vec![
400            (ValueRef::String("a"), ValueRef::Number(Number::NegativeInt(-1)))
401        ])
402    )]
403    fn decode_value_ref_cases(#[case] input: &[u8], #[case] expected: ValueRef<'_>) {
404        let v = from_slice::<ValueRef<'_>>(input).unwrap();
405        assert_eq!(v, expected);
406    }
407
408    // Verify extension encoding/decoding via ValueRef::Extension.
409    #[test]
410    fn encode_value_ref_extension_fixext1() {
411        let kind: i8 = 10;
412        let v = ValueRef::Extension(ExtensionRef::new(kind, &[0x12]));
413        let mut buf = [0u8; 3];
414        let len = to_slice(&v, &mut buf).unwrap();
415        assert_eq!(len, 3);
416        assert_eq!(buf, [0xd4, kind as u8, 0x12]);
417    }
418
419    // Round-trip timestamp 32 (ext type -1, 4-byte seconds field).
420    #[test]
421    fn decode_then_reencode_value_ref_extension_timestamp32_roundtrip() {
422        let ts32: &[u8] = &[0xd6, 0xff, 0x00, 0x00, 0x00, 0x00];
423        let v = from_slice::<ValueRef<'_>>(ts32).unwrap();
424        match v {
425            ValueRef::Extension(ext) => {
426                assert_eq!(ext.r#type, -1);
427                assert_eq!(ext.data, &[0x00, 0x00, 0x00, 0x00]);
428
429                // Re-encode and compare with original bytes
430                let mut buf = [0u8; 6];
431                let len = to_slice(&ValueRef::Extension(ext), &mut buf).unwrap();
432                assert_eq!(&buf[..len], ts32);
433            }
434            _ => panic!("expected extension"),
435        }
436    }
437
438    // {
439    //   "meta": {
440    //     "id": 1001,
441    //     "tags": ["sample", null, 42, {"extra": "yes"}]
442    //   },
443    //   "users": [
444    //     {
445    //       "name": "Alice",
446    //       "attributes": {
447    //         "age": 29,
448    //         "preferences": [
449    //           "coffee",
450    //           null,
451    //           {"music": ["jazz", "rock", {"genres": ["classical", 123]}]}
452    //         ]
453    //       }
454    //     },
455    //     {
456    //       "name": "Bob",
457    //       "attributes": {
458    //         "age": null,
459    //         "preferences": [
460    //           {"food": ["pizza", "sushi", null]},
461    //           [true, false, {"nested": [0, {"inner": "value"}]}]
462    //         ]
463    //       }
464    //     }
465    //   ]
466    // }
467    const COMPLEX: &[u8] = &[
468        0x82, 0xa4, 0x6d, 0x65, 0x74, 0x61, 0x82, 0xa2, 0x69, 0x64, 0xcd, 0x03, 0xe9, 0xa4, 0x74,
469        0x61, 0x67, 0x73, 0x94, 0xa6, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0xc0, 0x2a, 0x81, 0xa5,
470        0x65, 0x78, 0x74, 0x72, 0x61, 0xa3, 0x79, 0x65, 0x73, 0xa5, 0x75, 0x73, 0x65, 0x72, 0x73,
471        0x92, 0x82, 0xa4, 0x6e, 0x61, 0x6d, 0x65, 0xa5, 0x41, 0x6c, 0x69, 0x63, 0x65, 0xaa, 0x61,
472        0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x82, 0xa3, 0x61, 0x67, 0x65, 0x1d,
473        0xab, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x93, 0xa6, 0x63,
474        0x6f, 0x66, 0x66, 0x65, 0x65, 0xc0, 0x81, 0xa5, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x93, 0xa4,
475        0x6a, 0x61, 0x7a, 0x7a, 0xa4, 0x72, 0x6f, 0x63, 0x6b, 0x81, 0xa6, 0x67, 0x65, 0x6e, 0x72,
476        0x65, 0x73, 0x92, 0xa9, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x7b, 0x82,
477        0xa4, 0x6e, 0x61, 0x6d, 0x65, 0xa3, 0x42, 0x6f, 0x62, 0xaa, 0x61, 0x74, 0x74, 0x72, 0x69,
478        0x62, 0x75, 0x74, 0x65, 0x73, 0x82, 0xa3, 0x61, 0x67, 0x65, 0xc0, 0xab, 0x70, 0x72, 0x65,
479        0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x92, 0x81, 0xa4, 0x66, 0x6f, 0x6f, 0x64,
480        0x93, 0xa5, 0x70, 0x69, 0x7a, 0x7a, 0x61, 0xa5, 0x73, 0x75, 0x73, 0x68, 0x69, 0xc0, 0x93,
481        0xc3, 0xc2, 0x81, 0xa6, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x92, 0x00, 0x81, 0xa5, 0x69,
482        0x6e, 0x6e, 0x65, 0x72, 0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65,
483    ];
484    #[test]
485    fn roundtrip_complex() {
486        let meta = ValueRef::Map(vec![
487            (ValueRef::String("id"), ValueRef::from(1001)),
488            (
489                ValueRef::String("tags"),
490                ValueRef::Array(vec![
491                    ValueRef::String("sample"),
492                    ValueRef::Nil,
493                    ValueRef::from(42),
494                    ValueRef::Map(vec![(ValueRef::String("extra"), ValueRef::String("yes"))]),
495                ]),
496            ),
497        ]);
498        let alice = ValueRef::Map(vec![
499            (ValueRef::String("name"), ValueRef::String("Alice")),
500            (
501                ValueRef::String("attributes"),
502                ValueRef::Map(vec![
503                    (ValueRef::String("age"), ValueRef::from(29)),
504                    (
505                        ValueRef::String("preferences"),
506                        ValueRef::Array(vec![
507                            ValueRef::String("coffee"),
508                            ValueRef::Nil,
509                            ValueRef::Map(vec![(
510                                ValueRef::String("music"),
511                                ValueRef::Array(vec![
512                                    ValueRef::String("jazz"),
513                                    ValueRef::String("rock"),
514                                    ValueRef::Map(vec![(
515                                        ValueRef::String("genres"),
516                                        ValueRef::Array(vec![
517                                            ValueRef::String("classical"),
518                                            ValueRef::from(123),
519                                        ]),
520                                    )]),
521                                ]),
522                            )]),
523                        ]),
524                    ),
525                ]),
526            ),
527        ]);
528        let bob = ValueRef::Map(vec![
529            (ValueRef::String("name"), ValueRef::String("Bob")),
530            (
531                ValueRef::String("attributes"),
532                ValueRef::Map(vec![
533                    (ValueRef::String("age"), ValueRef::Nil),
534                    (
535                        ValueRef::String("preferences"),
536                        ValueRef::Array(vec![
537                            ValueRef::Map(vec![(
538                                ValueRef::String("food"),
539                                ValueRef::Array(vec![
540                                    ValueRef::String("pizza"),
541                                    ValueRef::String("sushi"),
542                                    ValueRef::Nil,
543                                ]),
544                            )]),
545                            ValueRef::Array(vec![
546                                ValueRef::Bool(true),
547                                ValueRef::Bool(false),
548                                ValueRef::Map(vec![(
549                                    ValueRef::String("nested"),
550                                    ValueRef::Array(vec![
551                                        ValueRef::from(0),
552                                        ValueRef::Map(vec![(
553                                            ValueRef::String("inner"),
554                                            ValueRef::String("value"),
555                                        )]),
556                                    ]),
557                                )]),
558                            ]),
559                        ]),
560                    ),
561                ]),
562            ),
563        ]);
564        let v = ValueRef::Map(vec![
565            (ValueRef::String("meta"), meta),
566            (ValueRef::String("users"), ValueRef::Array(vec![alice, bob])),
567        ]);
568
569        let deserialized = from_slice::<ValueRef<'_>>(COMPLEX).unwrap();
570        assert_eq!(deserialized, v);
571
572        let mut buf = [0u8; COMPLEX.len()];
573        let len = to_slice(&v, &mut buf).unwrap();
574        assert_eq!(len, COMPLEX.len());
575        assert_eq!(&buf, COMPLEX);
576    }
577}