cbor/
types.rs

1// This Source Code Form is subject to the terms of
2// the Mozilla Public License, v. 2.0. If a copy of
3// the MPL was not distributed with this file, You
4// can obtain one at http://mozilla.org/MPL/2.0/.
5
6//! CBOR types and tags definitions.
7
8use byteorder::{ReadBytesExt};
9use std::io::Error;
10
11/// The CBOR types.
12#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
13pub enum Type {
14    Array,
15    Bool,
16    Break,
17    Bytes,
18    Float16,
19    Float32,
20    Float64,
21    Int16,
22    Int32,
23    Int64,
24    Int8,
25    Null,
26    Object,
27    Tagged,
28    Text,
29    UInt16,
30    UInt32,
31    UInt64,
32    UInt8,
33    Undefined,
34    Unknown { major: u8, info: u8 },
35    Reserved { major: u8, info: u8 },
36    Unassigned { major: u8, info: u8 }
37}
38
39impl Type {
40    pub fn major(&self) -> u8 {
41        match *self {
42            Type::Array => 4,
43            Type::Bool  => 7,
44            Type::Break => 7,
45            Type::Bytes => 2,
46            Type::Float16 => 7,
47            Type::Float32 => 7,
48            Type::Float64 => 7,
49            Type::Int16   => 1,
50            Type::Int32   => 1,
51            Type::Int64   => 1,
52            Type::Int8    => 1,
53            Type::Null    => 7,
54            Type::Object  => 5,
55            Type::Tagged  => 6,
56            Type::Text    => 3,
57            Type::UInt16  => 0,
58            Type::UInt32  => 0,
59            Type::UInt64  => 0,
60            Type::UInt8   => 0,
61            Type::Undefined => 7,
62            Type::Unknown { major: m, .. } => m,
63            Type::Reserved { major: m, .. } => m,
64            Type::Unassigned { major: m, .. } => m
65        }
66    }
67
68    pub fn read<R: ReadBytesExt>(r: &mut R) -> Result<(Type, u8), Error> {
69        let b = r.read_u8()?;
70        match ((b & 0b111_00000) >> 5, b & 0b000_11111) {
71            (0, a @ 0...24)  => Ok((Type::UInt8, a)),
72            (0, 25)          => Ok((Type::UInt16, 25)),
73            (0, 26)          => Ok((Type::UInt32, 26)),
74            (0, 27)          => Ok((Type::UInt64, 27)),
75            (1, a @ 0...24)  => Ok((Type::Int8, a)),
76            (1, 25)          => Ok((Type::Int16, 25)),
77            (1, 26)          => Ok((Type::Int32, 26)),
78            (1, 27)          => Ok((Type::Int64, 27)),
79            (2, a)           => Ok((Type::Bytes, a)),
80            (3, a)           => Ok((Type::Text, a)),
81            (4, a)           => Ok((Type::Array, a)),
82            (5, a)           => Ok((Type::Object, a)),
83            (6, a)           => Ok((Type::Tagged, a)),
84            (7, a @ 0...19)  => Ok((Type::Unassigned { major: 7, info: a }, a)),
85            (7, 20)          => Ok((Type::Bool, 20)),
86            (7, 21)          => Ok((Type::Bool, 21)),
87            (7, 22)          => Ok((Type::Null, 22)),
88            (7, 23)          => Ok((Type::Undefined, 23)),
89            (7, 24)          => match r.read_u8()? {
90                a @ 0...31 => Ok((Type::Reserved { major: 7, info: a }, a)),
91                a          => Ok((Type::Unassigned { major: 7, info: a }, a))
92            },
93            (7, 25)          => Ok((Type::Float16, 25)),
94            (7, 26)          => Ok((Type::Float32, 26)),
95            (7, 27)          => Ok((Type::Float64, 27)),
96            (7, a @ 28...30) => Ok((Type::Unassigned { major: 7, info: a }, a)),
97            (7, 31)          => Ok((Type::Break, 31)),
98            (m, a)           => Ok((Type::Unknown { major: m, info: a }, a))
99        }
100    }
101}
102
103/// CBOR tags (corresponding to `Type::Tagged`).
104#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
105pub enum Tag {
106    DateTime,
107    Timestamp,
108    Bignum,
109    NegativeBignum,
110    Decimal,
111    Bigfloat,
112    Unassigned(u64),
113    ToBase64Url,
114    ToBase64,
115    ToBase16,
116    Cbor,
117    Uri,
118    Base64Url,
119    Base64,
120    Regex,
121    Mime,
122    CborSelf
123}
124
125impl Tag {
126    pub fn of(x: u64) -> Tag {
127        match x {
128            0     => Tag::DateTime,
129            1     => Tag::Timestamp,
130            2     => Tag::Bignum,
131            3     => Tag::NegativeBignum,
132            4     => Tag::Decimal,
133            5     => Tag::Bigfloat,
134            21    => Tag::ToBase64Url,
135            22    => Tag::ToBase64,
136            23    => Tag::ToBase16,
137            24    => Tag::Cbor,
138            32    => Tag::Uri,
139            33    => Tag::Base64Url,
140            34    => Tag::Base64,
141            35    => Tag::Regex,
142            36    => Tag::Mime,
143            55799 => Tag::CborSelf,
144            _     => Tag::Unassigned(x)
145        }
146    }
147
148    pub fn to(&self) -> u64 {
149        match *self {
150            Tag::DateTime       => 0,
151            Tag::Timestamp      => 1,
152            Tag::Bignum         => 2,
153            Tag::NegativeBignum => 3,
154            Tag::Decimal        => 4,
155            Tag::Bigfloat       => 5,
156            Tag::ToBase64Url    => 21,
157            Tag::ToBase64       => 22,
158            Tag::ToBase16       => 23,
159            Tag::Cbor           => 24,
160            Tag::Uri            => 32,
161            Tag::Base64Url      => 33,
162            Tag::Base64         => 34,
163            Tag::Regex          => 35,
164            Tag::Mime           => 36,
165            Tag::CborSelf       => 55799,
166            Tag::Unassigned(x)  => x
167        }
168    }
169}