1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
const FIXSTR_SIZE   : u8 = 0x1f;
const FIXARRAY_SIZE : u8 = 0x0f;
const FIXMAP_SIZE   : u8 = 0x0f;

#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Marker {
    FixPos(u8),
    FixNeg(i8),
    Null,
    True,
    False,
    U8,
    U16,
    U32,
    U64,
    I8,
    I16,
    I32,
    I64,
    F32,
    F64,
    FixStr(u8),
    Str8,
    Str16,
    Str32,
    Bin8,
    Bin16,
    Bin32,
    FixArray(u8),
    Array16,
    Array32,
    FixMap(u8),
    Map16,
    Map32,
    FixExt1,
    FixExt2,
    FixExt4,
    FixExt8,
    FixExt16,
    Ext8,
    Ext16,
    Ext32,
    Reserved,
}

impl Marker {
    pub fn from_u8(n: u8) -> Marker {
        match n {
            0x00 ... 0x7f => Marker::FixPos(n),
            0xe0 ... 0xff => Marker::FixNeg(n as i8),
            0x80 ... 0x8f => Marker::FixMap(n & FIXMAP_SIZE),
            0x90 ... 0x9f => Marker::FixArray(n & FIXARRAY_SIZE),
            0xa0 ... 0xbf => Marker::FixStr(n & FIXSTR_SIZE),
            0xc0 => Marker::Null,
            /// Marked in MessagePack spec as never used.
            0xc1 => Marker::Reserved,
            0xc2 => Marker::False,
            0xc3 => Marker::True,
            0xc4 => Marker::Bin8,
            0xc5 => Marker::Bin16,
            0xc6 => Marker::Bin32,
            0xc7 => Marker::Ext8,
            0xc8 => Marker::Ext16,
            0xc9 => Marker::Ext32,
            0xca => Marker::F32,
            0xcb => Marker::F64,
            0xcc => Marker::U8,
            0xcd => Marker::U16,
            0xce => Marker::U32,
            0xcf => Marker::U64,
            0xd0 => Marker::I8,
            0xd1 => Marker::I16,
            0xd2 => Marker::I32,
            0xd3 => Marker::I64,
            0xd4 => Marker::FixExt1,
            0xd5 => Marker::FixExt2,
            0xd6 => Marker::FixExt4,
            0xd7 => Marker::FixExt8,
            0xd8 => Marker::FixExt16,
            0xd9 => Marker::Str8,
            0xda => Marker::Str16,
            0xdb => Marker::Str32,
            0xdc => Marker::Array16,
            0xdd => Marker::Array32,
            0xde => Marker::Map16,
            0xdf => Marker::Map32,
            _ => unreachable!(),
        }
    }

    pub fn to_u8(&self) -> u8 {
        match *self {
            Marker::FixPos(val)   => val,
            Marker::FixNeg(val)   => val as u8,

            Marker::Null          => 0xc0,

            Marker::True          => 0xc3,
            Marker::False         => 0xc2,

            Marker::U8            => 0xcc,
            Marker::U16           => 0xcd,
            Marker::U32           => 0xce,
            Marker::U64           => 0xcf,

            Marker::I8            => 0xd0,
            Marker::I16           => 0xd1,
            Marker::I32           => 0xd2,
            Marker::I64           => 0xd3,

            Marker::F32           => 0xca,
            Marker::F64           => 0xcb,

            Marker::FixStr(len)   => 0xa0 | (len & FIXSTR_SIZE),
            Marker::Str8          => 0xd9,
            Marker::Str16         => 0xda,
            Marker::Str32         => 0xdb,

            Marker::Bin8          => 0xc4,
            Marker::Bin16         => 0xc5,
            Marker::Bin32         => 0xc6,

            Marker::FixArray(len) => 0x90 | (len & FIXARRAY_SIZE),
            Marker::Array16       => 0xdc,
            Marker::Array32       => 0xdd,

            Marker::FixMap(len)   => 0x80 | (len & FIXMAP_SIZE),
            Marker::Map16         => 0xde,
            Marker::Map32         => 0xdf,

            Marker::FixExt1       => 0xd4,
            Marker::FixExt2       => 0xd5,
            Marker::FixExt4       => 0xd6,
            Marker::FixExt8       => 0xd7,
            Marker::FixExt16      => 0xd8,
            Marker::Ext8          => 0xc7,
            Marker::Ext16         => 0xc8,
            Marker::Ext32         => 0xc9,

            Marker::Reserved      => 0xc1,
        }
    }
}