msgpack_value/
lib.rs

1//! The MessagePack Data Model
2//!
3//! See also the [specification](https://github.com/msgpack/msgpack/blob/master/spec.md).
4#[cfg(feature = "proptest")]
5use proptest::prelude::*;
6#[cfg(feature = "proptest")]
7use proptest_derive::Arbitrary;
8use std::convert::{TryFrom, TryInto};
9use thiserror::Error;
10
11/// Integer ranging from `-(2^63)` to `(2^64)-1`.
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub struct Int {
14    sign: bool,
15    /// Whenever `sign` is true, `value & (1 << 63)` is nonzero.
16    value: u64,
17}
18
19impl From<u64> for Int {
20    fn from(v: u64) -> Self {
21        Self {
22            sign: false,
23            value: v,
24        }
25    }
26}
27
28impl From<i64> for Int {
29    fn from(v: i64) -> Self {
30        if v >= 0 {
31            (v as u64).into()
32        } else {
33            Self {
34                sign: true,
35                value: v as u64,
36            }
37        }
38    }
39}
40
41impl From<u8> for Int {
42    fn from(v: u8) -> Self {
43        (v as u64).into()
44    }
45}
46
47impl From<u16> for Int {
48    fn from(v: u16) -> Self {
49        (v as u64).into()
50    }
51}
52
53impl From<u32> for Int {
54    fn from(v: u32) -> Self {
55        (v as u64).into()
56    }
57}
58
59#[cfg(any(
60    target_pointer_width = "16",
61    target_pointer_width = "32",
62    target_pointer_width = "64"
63))]
64impl From<usize> for Int {
65    fn from(v: usize) -> Self {
66        (v as u64).into()
67    }
68}
69
70impl From<i8> for Int {
71    fn from(v: i8) -> Self {
72        (v as i64).into()
73    }
74}
75
76impl From<i16> for Int {
77    fn from(v: i16) -> Self {
78        (v as i64).into()
79    }
80}
81
82impl From<i32> for Int {
83    fn from(v: i32) -> Self {
84        (v as i64).into()
85    }
86}
87
88#[cfg(any(
89    target_pointer_width = "16",
90    target_pointer_width = "32",
91    target_pointer_width = "64"
92))]
93impl From<isize> for Int {
94    fn from(v: isize) -> Self {
95        (v as i64).into()
96    }
97}
98
99impl std::fmt::Display for Int {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        if self.sign {
102            (self.value as i64).fmt(f)
103        } else {
104            self.value.fmt(f)
105        }
106    }
107}
108
109/// Error type returned by `TryFrom<Int>` implementations.
110#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
111#[error("out of range integral type conversion attempted")]
112pub struct TryFromIntError(());
113
114impl TryFrom<Int> for u64 {
115    type Error = TryFromIntError;
116
117    fn try_from(value: Int) -> Result<Self, Self::Error> {
118        if value.sign {
119            Err(TryFromIntError(()))
120        } else {
121            Ok(value.value)
122        }
123    }
124}
125
126impl TryFrom<Int> for i64 {
127    type Error = TryFromIntError;
128
129    fn try_from(value: Int) -> Result<Self, Self::Error> {
130        if value.sign {
131            Ok(value.value as i64)
132        } else {
133            let v = value.value as i64;
134            if v >= 0 {
135                Ok(v)
136            } else {
137                Err(TryFromIntError(()))
138            }
139        }
140    }
141}
142
143impl TryFrom<Int> for u8 {
144    type Error = TryFromIntError;
145
146    fn try_from(value: Int) -> Result<Self, Self::Error> {
147        u64::try_from(value)?
148            .try_into()
149            .map_err(|_| TryFromIntError(()))
150    }
151}
152
153impl TryFrom<Int> for u16 {
154    type Error = TryFromIntError;
155
156    fn try_from(value: Int) -> Result<Self, Self::Error> {
157        u64::try_from(value)?
158            .try_into()
159            .map_err(|_| TryFromIntError(()))
160    }
161}
162
163impl TryFrom<Int> for u32 {
164    type Error = TryFromIntError;
165
166    fn try_from(value: Int) -> Result<Self, Self::Error> {
167        u64::try_from(value)?
168            .try_into()
169            .map_err(|_| TryFromIntError(()))
170    }
171}
172
173impl TryFrom<Int> for usize {
174    type Error = TryFromIntError;
175
176    fn try_from(value: Int) -> Result<Self, Self::Error> {
177        u64::try_from(value)?
178            .try_into()
179            .map_err(|_| TryFromIntError(()))
180    }
181}
182
183impl TryFrom<Int> for i8 {
184    type Error = TryFromIntError;
185
186    fn try_from(value: Int) -> Result<Self, Self::Error> {
187        i64::try_from(value)?
188            .try_into()
189            .map_err(|_| TryFromIntError(()))
190    }
191}
192
193impl TryFrom<Int> for i16 {
194    type Error = TryFromIntError;
195
196    fn try_from(value: Int) -> Result<Self, Self::Error> {
197        i64::try_from(value)?
198            .try_into()
199            .map_err(|_| TryFromIntError(()))
200    }
201}
202
203impl TryFrom<Int> for i32 {
204    type Error = TryFromIntError;
205
206    fn try_from(value: Int) -> Result<Self, Self::Error> {
207        i64::try_from(value)?
208            .try_into()
209            .map_err(|_| TryFromIntError(()))
210    }
211}
212
213#[cfg(any(
214    target_pointer_width = "16",
215    target_pointer_width = "32",
216    target_pointer_width = "64"
217))]
218impl TryFrom<Int> for isize {
219    type Error = TryFromIntError;
220
221    fn try_from(value: Int) -> Result<Self, Self::Error> {
222        i64::try_from(value)?
223            .try_into()
224            .map_err(|_| TryFromIntError(()))
225    }
226}
227
228#[cfg(feature = "proptest")]
229impl Arbitrary for Int {
230    type Parameters = ();
231
232    type Strategy = BoxedStrategy<Int>;
233
234    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
235        (any::<i64>(), any::<bool>())
236            .prop_map(|(high, low)| {
237                if high < 0 {
238                    Int::from(high)
239                } else {
240                    Int::from((high as u64) << 1 | (low as u64))
241                }
242            })
243            .boxed()
244    }
245}
246
247/// String objects of MessagePack are essentially byte arrays type that may contain any bytes.
248///
249/// # String type vs Binary type
250///
251/// MessagePack has a complicated history about its distinction between string type and binary type.
252///
253/// While an earlier version of MessagePack had only one type for encoding a binary data, namely the raw type,
254/// it was later divided into two distinct types for supporting use cases in dynamically-typed languages. [^1]
255/// The string type, one of the newly added types, is essentially what was originally called the raw type.
256/// Because of this origin, despite its name, string objects of MessagePack can contain not just valid UTF-8 sequences but also any byte sequences.
257/// And encoding non-UTF-8 byte sequences as a string object is a *perfectly valid* and *expected* usage by the spec authors.
258///
259/// [^1]: [https://github.com/msgpack/msgpack/issues/121](https://github.com/msgpack/msgpack/issues/121)
260///
261/// # So which to use in encoding my binary data?
262///
263/// When you decide to implement a custom serializer/deserializer for your own binary type,
264/// it is recommended to use _string type_ instead of binary type for its encoding scheme for the following reasons.
265///
266/// - It just saves some memory. If your byte array is less than 32 byte length, using string type instead of byte array saves one byte per object.
267/// - The disiction only matters when _not_ using a data schema. Because this crate offers a statically-typed data schema, and we know how to decode data into a Rust object at compile time,
268/// distinction of these types in the input binary data is almost useless,
269///
270/// Although we strongly recommend you to use string types rather than binary types, this crate does _not_ force you to do so.
271/// The functions and trait implementations provided by this crate are all taking a neutral stand.
272#[cfg_attr(feature = "proptest", derive(Arbitrary))]
273#[derive(Debug, Clone, PartialEq, Eq)]
274pub struct Str(pub Vec<u8>);
275
276impl From<String> for Str {
277    fn from(x: String) -> Self {
278        Str(x.into_bytes())
279    }
280}
281
282impl Str {
283    pub fn into_bytes(self) -> Vec<u8> {
284        self.0
285    }
286
287    pub fn as_bytes(&self) -> &[u8] {
288        &self.0
289    }
290}
291
292/// Byte array type.
293///
294/// As noted in the comment in [Str], using this type in this crate is almost nonsense, unless your data schema is shared by some external data providers.
295#[cfg_attr(feature = "proptest", derive(Arbitrary))]
296#[derive(Debug, Clone, PartialEq, Eq)]
297pub struct Bin(pub Vec<u8>);
298
299impl Bin {
300    pub fn into_bytes(self) -> Vec<u8> {
301        self.0
302    }
303
304    pub fn as_bytes(&self) -> &[u8] {
305        &self.0
306    }
307}
308
309/// User-extended type.
310#[cfg_attr(feature = "proptest", derive(Arbitrary))]
311#[derive(Debug, Clone, PartialEq, Eq)]
312pub struct Ext {
313    pub r#type: i8,
314    pub data: Vec<u8>,
315}
316
317#[derive(Clone, PartialEq, Debug, Default)]
318pub enum Value {
319    #[default]
320    Nil,
321    Bool(bool),
322    Int(Int),
323    F32(f32),
324    F64(f64),
325    Str(Str),
326    Bin(Bin),
327    Array(Vec<Value>),
328    Map(Vec<(Value, Value)>),
329    Ext(Ext),
330}
331
332impl From<bool> for Value {
333    fn from(v: bool) -> Self {
334        Self::Bool(v)
335    }
336}
337
338impl From<Int> for Value {
339    fn from(v: Int) -> Self {
340        Self::Int(v)
341    }
342}
343
344impl From<u8> for Value {
345    fn from(v: u8) -> Self {
346        Self::Int(v.into())
347    }
348}
349
350impl From<u16> for Value {
351    fn from(v: u16) -> Self {
352        Self::Int(v.into())
353    }
354}
355
356impl From<u32> for Value {
357    fn from(v: u32) -> Self {
358        Self::Int(v.into())
359    }
360}
361
362impl From<u64> for Value {
363    fn from(v: u64) -> Self {
364        Self::Int(v.into())
365    }
366}
367
368impl From<usize> for Value {
369    fn from(v: usize) -> Self {
370        Self::Int(v.into())
371    }
372}
373
374impl From<i8> for Value {
375    fn from(v: i8) -> Self {
376        Self::Int(v.into())
377    }
378}
379
380impl From<i16> for Value {
381    fn from(v: i16) -> Self {
382        Self::Int(v.into())
383    }
384}
385
386impl From<i32> for Value {
387    fn from(v: i32) -> Self {
388        Self::Int(v.into())
389    }
390}
391
392impl From<i64> for Value {
393    fn from(v: i64) -> Self {
394        Self::Int(v.into())
395    }
396}
397
398impl From<isize> for Value {
399    fn from(v: isize) -> Self {
400        Self::Int(v.into())
401    }
402}
403
404impl From<f32> for Value {
405    fn from(v: f32) -> Self {
406        Self::F32(v)
407    }
408}
409
410impl From<f64> for Value {
411    fn from(v: f64) -> Self {
412        Self::F64(v)
413    }
414}
415
416impl From<Str> for Value {
417    fn from(v: Str) -> Self {
418        Self::Str(v)
419    }
420}
421
422impl From<String> for Value {
423    fn from(v: String) -> Self {
424        Self::Str(Str(v.into_bytes()))
425    }
426}
427
428impl From<&str> for Value {
429    fn from(v: &str) -> Self {
430        v.to_owned().into()
431    }
432}
433
434impl From<Bin> for Value {
435    fn from(v: Bin) -> Self {
436        Self::Bin(v)
437    }
438}
439
440impl From<Ext> for Value {
441    fn from(v: Ext) -> Self {
442        Self::Ext(v)
443    }
444}
445
446impl From<Vec<Value>> for Value {
447    fn from(v: Vec<Value>) -> Self {
448        Self::Array(v)
449    }
450}
451
452impl From<Vec<(Value, Value)>> for Value {
453    fn from(v: Vec<(Value, Value)>) -> Self {
454        Self::Map(v)
455    }
456}
457
458pub trait Index {
459    fn index<'a>(&self, v: &'a Value) -> &'a Value;
460}
461
462impl<T: Index + ?Sized> Index for &T {
463    fn index<'a>(&self, v: &'a Value) -> &'a Value {
464        (*self).index(v)
465    }
466}
467
468impl Index for str {
469    fn index<'a>(&self, v: &'a Value) -> &'a Value {
470        let map = v
471            .as_map()
472            .expect("this type of object is not indexable by str");
473        for (key, value) in map.iter().rev() {
474            if let Some(Str(key)) = key.as_str() {
475                if key == self.as_bytes() {
476                    return value;
477                }
478            }
479        }
480        panic!("key not found in object");
481    }
482}
483
484impl Index for String {
485    fn index<'a>(&self, v: &'a Value) -> &'a Value {
486        self.as_str().index(v)
487    }
488}
489
490impl Index for usize {
491    fn index<'a>(&self, v: &'a Value) -> &'a Value {
492        let array = v
493            .as_array()
494            .expect("this type of object is not indexable by usize");
495        &array[*self]
496    }
497}
498
499impl<T> core::ops::Index<T> for Value
500where
501    T: Index,
502{
503    type Output = Value;
504    /// Accessing inner values of `value` using indexing `value[0]` or `value["foo"]`.
505    ///
506    /// # Panics
507    ///
508    /// This function panics when `self` does not contain given key.
509    ///
510    /// # Duplicate keys
511    ///
512    /// If `self` is a map object and contains two or more keys matching against the given index,
513    /// indexing works as if the preceding keys do not exist in the object.
514    /// This is the same behaviour as [what EMCA-262 specifies](https://stackoverflow.com/a/23195243).
515    ///
516    /// ```
517    /// # use msgpack_value::{msgpack, Int};
518    /// let v = msgpack!({ "a" : 0, "a" : 1 });
519    /// assert_eq!(v["a"], Int::from(1u32).into());
520    /// ```
521    fn index(&self, index: T) -> &Self::Output {
522        index.index(self)
523    }
524}
525
526#[test]
527fn test_index() {
528    let v = msgpack!({ 0: 1, "foo" : "bar", "foo" : "baz" });
529    let k = &v["foo"];
530    // last value wins
531    assert_eq!(k.as_str().unwrap().as_bytes(), "baz".as_bytes());
532
533    let v = msgpack!(["foo", "bar", "baz"]);
534    let k = &v[1];
535    assert_eq!(k.as_str().unwrap().as_bytes(), "bar".as_bytes());
536}
537
538#[test]
539#[should_panic]
540fn test_index_panic_array_index_by_str() {
541    let _ = msgpack!([])["foo"];
542}
543
544#[test]
545#[should_panic]
546fn test_index_panic_array_out_of_range() {
547    let _ = msgpack!([])[0];
548}
549
550#[test]
551#[should_panic]
552fn test_index_panic_map_key_not_found() {
553    let _ = msgpack!({"foo":"bar"})["baz"];
554}
555
556/// Error type returned by `TryFrom<Value>` implementations.
557#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
558#[error("value is not of the expected type")]
559pub struct TryFromValueError(());
560
561impl TryFrom<Value> for bool {
562    type Error = TryFromValueError;
563
564    fn try_from(value: Value) -> Result<Self, Self::Error> {
565        match value {
566            Value::Bool(v) => Ok(v),
567            _ => Err(TryFromValueError(())),
568        }
569    }
570}
571
572impl TryFrom<Value> for Int {
573    type Error = TryFromValueError;
574
575    fn try_from(value: Value) -> Result<Self, Self::Error> {
576        match value {
577            Value::Int(v) => Ok(v),
578            _ => Err(TryFromValueError(())),
579        }
580    }
581}
582
583impl TryFrom<Value> for f32 {
584    type Error = TryFromValueError;
585
586    fn try_from(value: Value) -> Result<Self, Self::Error> {
587        match value {
588            Value::F32(v) => Ok(v),
589            _ => Err(TryFromValueError(())),
590        }
591    }
592}
593
594impl TryFrom<Value> for f64 {
595    type Error = TryFromValueError;
596
597    fn try_from(value: Value) -> Result<Self, Self::Error> {
598        match value {
599            Value::F64(v) => Ok(v),
600            _ => Err(TryFromValueError(())),
601        }
602    }
603}
604
605impl TryFrom<Value> for Vec<Value> {
606    type Error = TryFromValueError;
607
608    fn try_from(value: Value) -> Result<Self, Self::Error> {
609        match value {
610            Value::Array(v) => Ok(v),
611            _ => Err(TryFromValueError(())),
612        }
613    }
614}
615
616impl TryFrom<Value> for Vec<(Value, Value)> {
617    type Error = TryFromValueError;
618
619    fn try_from(value: Value) -> Result<Self, Self::Error> {
620        match value {
621            Value::Map(v) => Ok(v),
622            _ => Err(TryFromValueError(())),
623        }
624    }
625}
626
627#[cfg(feature = "proptest")]
628impl Arbitrary for Value {
629    type Parameters = ();
630    type Strategy = BoxedStrategy<Value>;
631
632    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
633        fn arb_value() -> BoxedStrategy<Value> {
634            let leaf = prop_oneof![
635                Just(Value::Nil),
636                any::<bool>().prop_map(Value::Bool),
637                any::<Int>().prop_map(Value::Int),
638                any::<f32>().prop_map(Value::F32),
639                any::<f64>().prop_map(Value::F64),
640                any::<Str>().prop_map(Value::Str),
641                any::<Bin>().prop_map(Value::Bin),
642                any::<Ext>().prop_map(Value::Ext),
643            ];
644            leaf.prop_recursive(8, 256, 10, |inner| {
645                prop_oneof![
646                    prop::collection::vec(inner.clone(), 0..10).prop_map(Value::Array),
647                    prop::collection::vec((inner.clone(), inner), 0..10).prop_map(Value::Map),
648                ]
649            })
650            .boxed()
651        }
652        arb_value()
653    }
654}
655
656impl Value {
657    pub fn is_nil(&self) -> bool {
658        matches!(self, Self::Nil)
659    }
660    pub fn is_bool(&self) -> bool {
661        matches!(self, Self::Bool(_))
662    }
663    pub fn is_int(&self) -> bool {
664        matches!(self, Self::Int(_))
665    }
666    pub fn is_f32(&self) -> bool {
667        matches!(self, Self::F32(_))
668    }
669    pub fn is_f64(&self) -> bool {
670        matches!(self, Self::F64(_))
671    }
672    pub fn is_str(&self) -> bool {
673        matches!(self, Self::Str(_))
674    }
675    pub fn is_bin(&self) -> bool {
676        matches!(self, Self::Bin(_))
677    }
678    pub fn is_array(&self) -> bool {
679        matches!(self, Self::Array(_))
680    }
681    pub fn is_map(&self) -> bool {
682        matches!(self, Self::Map(_))
683    }
684    pub fn is_ext(&self) -> bool {
685        matches!(self, Self::Ext(_))
686    }
687    pub fn as_bool(&self) -> Option<bool> {
688        match self {
689            Self::Bool(v) => Some(*v),
690            _ => None,
691        }
692    }
693    pub fn as_int(&self) -> Option<Int> {
694        match self {
695            Self::Int(v) => Some(*v),
696            _ => None,
697        }
698    }
699    pub fn as_f32(&self) -> Option<f32> {
700        match self {
701            Self::F32(v) => Some(*v),
702            _ => None,
703        }
704    }
705    pub fn as_f64(&self) -> Option<f64> {
706        match self {
707            Self::F64(v) => Some(*v),
708            _ => None,
709        }
710    }
711    pub fn as_str(&self) -> Option<&Str> {
712        match self {
713            Self::Str(v) => Some(v),
714            _ => None,
715        }
716    }
717    pub fn as_str_mut(&mut self) -> Option<&mut Str> {
718        match self {
719            Self::Str(v) => Some(v),
720            _ => None,
721        }
722    }
723    pub fn as_bin(&self) -> Option<&Bin> {
724        match self {
725            Self::Bin(v) => Some(v),
726            _ => None,
727        }
728    }
729    pub fn as_bin_mut(&mut self) -> Option<&mut Bin> {
730        match self {
731            Self::Bin(v) => Some(v),
732            _ => None,
733        }
734    }
735    pub fn as_array(&self) -> Option<&[Value]> {
736        match self {
737            Self::Array(v) => Some(v),
738            _ => None,
739        }
740    }
741    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
742        match self {
743            Self::Array(v) => Some(v),
744            _ => None,
745        }
746    }
747    pub fn as_map(&self) -> Option<&[(Value, Value)]> {
748        match self {
749            Self::Map(v) => Some(v),
750            _ => None,
751        }
752    }
753    pub fn as_map_mut(&mut self) -> Option<&mut Vec<(Value, Value)>> {
754        match self {
755            Self::Map(v) => Some(v),
756            _ => None,
757        }
758    }
759    pub fn as_ext(&self) -> Option<&Ext> {
760        match self {
761            Self::Ext(v) => Some(v),
762            _ => None,
763        }
764    }
765    pub fn as_ext_mut(&mut self) -> Option<&mut Ext> {
766        match self {
767            Self::Ext(v) => Some(v),
768            _ => None,
769        }
770    }
771}
772
773#[doc(hidden)]
774#[macro_export]
775macro_rules! msgpack_array {
776    ($acc: ident) => {
777    };
778    ($acc: ident,) => {
779    };
780    ($acc: ident nil) => {
781        $acc.push($crate::msgpack_value!(nil));
782    };
783    ($acc: ident nil, $( $rest: tt )*) => {
784        $acc.push($crate::msgpack_value!(nil));
785        $crate::msgpack_array!($acc $( $rest )*);
786    };
787    ($acc: ident [ $( $tt: tt )* ]) => {
788        $acc.push($crate::msgpack_value!([ $( $tt )* ]));
789    };
790    ($acc: ident [ $( $tt: tt )* ], $( $rest: tt )*) => {
791        $acc.push($crate::msgpack_value!([ $( $tt )* ]));
792        $crate::msgpack_array!($acc $( $rest )*);
793    };
794    ($acc: ident { $( $tt: tt )* }) => {
795        $acc.push($crate::msgpack_value!({ $( $tt )* }));
796    };
797    ($acc: ident { $( $tt: tt )* }, $( $rest: tt )*) => {
798        $acc.push($crate::msgpack_value!({ $( $tt )* }));
799        $crate::msgpack_array!($acc $( $rest )*);
800    };
801    ($acc: ident $expr: expr) => {
802        $acc.push($crate::msgpack_value!($expr));
803    };
804    ($acc: ident $expr: expr, $( $rest: tt )*) => {
805        $acc.push($crate::msgpack_value!($expr));
806        $crate::msgpack_array!($acc $( $rest )*);
807    };
808}
809
810#[doc(hidden)]
811#[macro_export]
812macro_rules! msgpack_map {
813    (@key $acc: ident []) => {
814    };
815    (@key $acc: ident [],) => {
816    };
817    (@key $acc: ident [ $( $key: tt )* ] : $( $rest: tt )*) => {
818        let key = $crate::msgpack_value!($( $key )*);
819        $crate::msgpack_map!(@val $acc key $( $rest )*);
820    };
821    (@key $acc: ident [ $( $key: tt )* ] $tt: tt $( $rest: tt )*) => {
822        $crate::msgpack_map!(@key $acc [ $( $key )* $tt ] $( $rest )*);
823    };
824    (@val $acc: ident $key: ident nil) => {
825        $acc.push(($key, $crate::msgpack_value!(nil)));
826    };
827    (@val $acc: ident $key: ident nil, $( $rest: tt )*) => {
828        $acc.push(($key, $crate::msgpack_value!(nil)));
829        $crate::msgpack_map!(@key $acc [] $( $rest )*);
830    };
831    (@val $acc: ident $key: ident [ $( $tt: tt )* ]) => {
832        $acc.push(($key, $crate::msgpack_value!([ $( $tt )* ])));
833    };
834    (@val $acc: ident $key: ident [ $( $tt: tt )* ], $( $rest: tt )*) => {
835        $acc.push(($key, $crate::msgpack_value!([ $( $tt )* ])));
836        $crate::msgpack_map!(@key $acc [] $( $rest )*);
837    };
838    (@val $acc: ident $key: ident { $( $tt: tt )* }) => {
839        $acc.push(($key, $crate::msgpack_value!({ $( $tt )* })));
840    };
841    (@val $acc: ident $key: ident { $( $tt: tt )* }, $( $rest: tt )*) => {
842        $acc.push(($key, $crate::msgpack_value!({ $( $tt )* })));
843        $crate::msgpack_map!(@key $acc [] $( $rest )*);
844    };
845    (@val $acc: ident $key: ident $expr: expr) => {
846        $acc.push(($key, $crate::msgpack_value!($expr)));
847    };
848    (@val $acc: ident $key: ident $expr: expr, $( $rest: tt )*) => {
849        $acc.push(($key, $crate::msgpack_value!($expr)));
850        $crate::msgpack_map!(@key $acc [] $( $rest )*);
851    };
852}
853
854#[doc(hidden)]
855#[macro_export]
856macro_rules! msgpack_value {
857    (nil) => {
858        $crate::Value::Nil
859    };
860    ([ $( $tt: tt )* ]) => {
861        {
862            #[allow(unused_mut)]
863            let mut array;
864            #[allow(clippy::vec_init_then_push)]
865            {
866                array = vec![];
867                $crate::msgpack_array!(array $( $tt )*);
868            }
869            $crate::Value::Array(array)
870        }
871    };
872    ({ $( $tt: tt )* }) => {
873        {
874            #[allow(unused_mut)]
875            let mut map;
876            #[allow(clippy::vec_init_then_push)]
877            {
878                map = vec![];
879                $crate::msgpack_map!(@key map [] $( $tt )*);
880            }
881            $crate::Value::Map(map)
882        }
883    };
884    ($other: expr) => {
885        $crate::Value::from($other)
886    };
887}
888
889/// Constructs a [Value] from literal.
890///
891/// # Example
892///
893/// ```
894/// # use msgpack_value::{msgpack, Bin, Int, Str, Value};
895/// let obj = msgpack!(
896///     // array literal
897///     [
898///     // numeric literals
899///     0,
900///     -42,
901///     3.14,
902///     2.71f32,
903///     // actually any expression is allowed (as long as it's a supported type)
904///     1 + 2 + 3,
905///     // boolean
906///     true,
907///     false,
908///     // nil is a keyword denoting the nil object
909///     nil,
910///     // string literal to make a string object
911///     "hello",
912///     // Use an expression of [Bin] type to create a binary object
913///     Bin(vec![0xDE, 0xAD, 0xBE, 0xEF]),
914///     // map object
915///     { "any value in key": nil },
916///     { 0: 1, "trailing comma is ok": nil, }
917///     ]
918/// );
919///
920/// assert_eq!(
921///     obj,
922///     Value::Array(vec![
923///         Value::Int(Int::from(0)),
924///         Value::Int(Int::from(-42)),
925///         Value::F64(3.14),
926///         Value::F32(2.71),
927///         Value::Int(Int::from(6)),
928///         Value::Bool(true),
929///         Value::Bool(false),
930///         Value::Nil,
931///         Value::Str(Str("hello".to_owned().into_bytes())),
932///         Value::Bin(Bin(vec![0xDE, 0xAD, 0xBE, 0xEF])),
933///         Value::Map(vec![(
934///             Value::Str(Str("any value in key".to_owned().into_bytes())),
935///             Value::Nil
936///         ),]),
937///         Value::Map(vec![
938///             (Value::Int(Int::from(0)), Value::Int(Int::from(1))),
939///             (
940///                 Value::Str(Str("trailing comma is ok".to_owned().into_bytes())),
941///                 Value::Nil
942///             ),
943///         ])
944///     ])
945/// )
946/// # ;
947/// ```
948#[macro_export]
949macro_rules! msgpack {
950    ($( $tt: tt )*) => {
951        $crate::msgpack_value!($( $tt )*)
952    };
953}
954
955#[cfg(test)]
956mod tests {
957    use super::*;
958
959    #[test]
960    fn roundtrip_int() {
961        assert_eq!(i64::MAX, Int::from(i64::MAX).try_into().unwrap());
962        assert_eq!(i64::MIN, Int::from(i64::MIN).try_into().unwrap());
963        assert_eq!(u64::MAX, Int::from(u64::MAX).try_into().unwrap());
964        assert_eq!(u64::MIN, Int::from(u64::MIN).try_into().unwrap());
965    }
966
967    #[test]
968    fn msgpack_macro() {
969        assert_eq!(Value::Int(Int::from(42)), msgpack!(42));
970        assert_eq!(Value::Int(Int::from(-42)), msgpack!(-42));
971        assert_eq!(Value::F64(1.23), msgpack!(1.23));
972        assert_eq!(Value::F32(1.23), msgpack!(1.23f32));
973        assert_eq!(
974            Value::Str(Str("hello world".to_owned().into_bytes())),
975            msgpack!("hello world")
976        );
977        assert_eq!(Value::Bool(true), msgpack!(true));
978        assert_eq!(Value::Bool(false), msgpack!(false));
979        assert_eq!(Value::Int(Int::from(7)), msgpack!(3 + 4));
980
981        assert_eq!(Value::Nil, msgpack!(nil));
982
983        assert_eq!(
984            Value::Array(vec![
985                msgpack!(42),
986                msgpack!(true),
987                msgpack!(nil),
988                msgpack!("hello"),
989            ]),
990            msgpack!([42, true, nil, "hello"])
991        );
992
993        assert_eq!(
994            Value::Array(vec![
995                msgpack!(42),
996                msgpack!(true),
997                msgpack!(nil),
998                msgpack!("hello"),
999            ]),
1000            msgpack!([42, true, nil, "hello",])
1001        );
1002
1003        assert_eq!(
1004            Value::Array(vec![
1005                msgpack!(42),
1006                Value::Array(vec![Value::Array(vec![msgpack!(true)]), msgpack!(nil),]),
1007                msgpack!("hello"),
1008            ]),
1009            msgpack!([42, [[true], nil], "hello",])
1010        );
1011
1012        assert_eq!(Value::Array(vec![]), msgpack!([]));
1013
1014        assert_eq!(
1015            Value::Map(vec![
1016                (msgpack!(42), msgpack!(true)),
1017                (msgpack!(nil), msgpack!("hello")),
1018            ]),
1019            msgpack!({ 42: true, nil: "hello", })
1020        );
1021
1022        assert_eq!(
1023            Value::Map(vec![
1024                (msgpack!(0), msgpack!(nil)),
1025                (msgpack!(1), msgpack!(nil)),
1026            ]),
1027            msgpack!({ 0: nil, 1: nil })
1028        );
1029
1030        assert_eq!(
1031            Value::Map(vec![
1032                (msgpack!(0), msgpack!({})),
1033                (msgpack!(1), msgpack!({})),
1034            ]),
1035            msgpack!({ 0: {}, 1: {} })
1036        );
1037
1038        assert_eq!(
1039            Value::Map(vec![
1040                (msgpack!(0), msgpack!([])),
1041                (msgpack!(1), msgpack!([])),
1042            ]),
1043            msgpack!({ 0: [], 1: [] })
1044        );
1045
1046        assert_eq!(
1047            Value::Map(vec![
1048                (msgpack!(0), msgpack!(-1)),
1049                (msgpack!(-1), msgpack!(0)),
1050            ]),
1051            msgpack!({ 0: -1, -1: 0 })
1052        );
1053
1054        assert_eq!(
1055            Value::Map(vec![
1056                (msgpack!(42), msgpack!({ true: false })),
1057                (msgpack!({ nil: 1.23 }), msgpack!("hello")),
1058            ]),
1059            msgpack!({ 42: { true: false }, { nil: 1.23 }: "hello", })
1060        );
1061        assert_eq!(Value::Map(vec![]), msgpack!({}));
1062
1063        assert_eq!(
1064            Value::Bin(Bin(vec![0xDEu8, 0xAD, 0xBE, 0xEF])),
1065            msgpack!(Bin(vec![0xDE, 0xAD, 0xBE, 0xEF]))
1066        );
1067
1068        assert_eq!(Value::Array(vec![msgpack!(-42)]), msgpack!([-42]));
1069    }
1070
1071    #[cfg(feature = "proptest")]
1072    proptest! {
1073        #[test]
1074        fn no_panic_arb_int(_ in any::<Int>()) {
1075            // pass
1076        }
1077
1078        #[test]
1079        fn no_panic_arb_value(_ in any::<Value>()) {
1080            // pass
1081        }
1082    }
1083}