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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
mod tags;

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
/// How many additional bytes are used to encode this integer (in bits).
///
/// See [RFC 7049 § 2][RFC 2].
///
/// [RFC 2]: https://tools.ietf.org/html/rfc7049#section-2
pub enum IntegerWidth {
    /// Parsed from CBOR diagnostic notation without an encoding indicator
    Unknown,
    /// For values <24 encoded directly in the additional data of the first byte
    Zero,
    /// One additional byte
    Eight,
    /// Two additional bytes
    Sixteen,
    /// Four additional bytes
    ThirtyTwo,
    /// Eight additional bytes
    SixtyFour,
}

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
/// How many additional bytes are used to encode this float (in bits).
///
/// See [RFC 7049 § 2][RFC 2].
///
/// [RFC 2]: https://tools.ietf.org/html/rfc7049#section-2
pub enum FloatWidth {
    /// Parsed from CBOR diagnostic notation without an encoding indicator
    Unknown,
    /// Two additional bytes
    Sixteen,
    /// Four additional bytes
    ThirtyTwo,
    /// Eight additional bytes
    SixtyFour,
}

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
/// A semantic tag for a CBOR data item.
///
/// See [RFC 7049 § 2.4: Table 3][RFC 2.4] and the [CBOR Tags IANA Registry][IANA]
///
/// [RFC 2.4]: https://tools.ietf.org/html/rfc7049#section-2.4
/// [IANA]: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
pub struct Tag(pub u64);

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
/// A "simple value" data item.
///
/// See [RFC 7049 § 2.3: Table 2][RFC 2.3].
///
/// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
pub struct Simple(pub u8);

#[derive(Debug, Eq, PartialEq, Clone)]
/// A string of raw bytes with no direct attached meaning.
///
/// May be assigned a meaning by being enclosed in a [semantic tag](Tag).
///
/// See [RFC 7049 § 2.1: Major type 2][RFC 2.1].
///
/// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
pub struct ByteString {
    /// The raw binary data in this byte string
    pub data: Vec<u8>,
    /// The bitwidth used for encoding the length
    pub bitwidth: IntegerWidth,
}

#[derive(Debug, Eq, PartialEq, Clone)]
/// A UTF-8 encoded text string.
///
/// May be assigned further meaning by being enclosed in a [semantic tag](Tag).
///
/// See [RFC 7049 § 2.1: Major type 3][RFC 2.1].
///
/// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
pub struct TextString {
    /// The textual data in this text string
    pub data: String,
    /// The bitwidth used for encoding the length
    pub bitwidth: IntegerWidth,
}

#[derive(Debug, PartialEq, Clone)]
/// A CBOR data item.
///
/// See [RFC 7049 § 1.2: Data item][RFC 1.2].
///
/// [RFC 1.2]: https://tools.ietf.org/html/rfc7049#section-1.2
pub enum DataItem {
    /// An unsigned integer.
    ///
    /// See [RFC 7049 § 2.1: Major type 0][RFC 2.1].
    ///
    /// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
    Integer {
        /// The value of this unsigned integer.
        value: u64,

        /// The bitwidth used for encoding this integer.
        bitwidth: IntegerWidth,
    },

    /// A negative integer.
    ///
    /// See [RFC 7049 § 2.1: Major type 0][RFC 2.1].
    ///
    /// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
    Negative {
        /// The encoded value of this negative integer, the real value is `-1 -
        /// value` (requires use of `i128` for full range support).
        value: u64,

        /// The bitwidth used for encoding this integer.
        bitwidth: IntegerWidth,
    },

    /// A string of raw bytes with no direct attached meaning.
    ///
    /// See the docs for [`ByteString`] for more details.
    ByteString(ByteString),

    /// A UTF-8 encoded text string.
    ///
    /// See the docs for [`TextString`] for more details.
    TextString(TextString),

    /// A series of [`ByteString`] chunks encoded as an indefinite length byte
    /// string.
    ///
    /// See [RFC 7049 § 2.2.2][RFC 2.2.2].
    ///
    /// [RFC 2.2.2]: https://tools.ietf.org/html/rfc7049#section-2.2.2
    IndefiniteByteString(Vec<ByteString>),

    /// A series of [`TextString`] chunks encoded as an indefinite length text
    /// string.
    ///
    /// See [RFC 7049 § 2.2.2][RFC 2.2.2].
    ///
    /// [RFC 2.2.2]: https://tools.ietf.org/html/rfc7049#section-2.2.2
    IndefiniteTextString(Vec<TextString>),

    /// An array of data items.
    ///
    /// See [RFC 7049 § 2.1: Major type 4][RFC 2.1].
    ///
    /// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
    Array {
        /// The data items in this array.
        data: Vec<DataItem>,

        /// The bitwidth used for encoding the array length.
        ///
        /// If has the value [`None`] then this array is encoded using the
        /// indefinite length form, see [RFC 7049 § 2.2.1][RFC 2.2.1].
        ///
        /// [RFC 2.2.1]: https://tools.ietf.org/html/rfc7049#section-2.2.1
        bitwidth: Option<IntegerWidth>,
    },

    /// A map of pairs of data items.
    ///
    /// See [RFC 7049 § 2.1: Major type 5][RFC 2.1].
    ///
    /// [RFC 2.1]: https://tools.ietf.org/html/rfc7049#section-2.1
    Map {
        /// The pairs of data items in this map.
        data: Vec<(DataItem, DataItem)>,

        /// The bitwidth used for encoding the map length.
        ///
        /// If has the value [`None`] then this map is encoded using the
        /// indefinite length form, see [RFC 7049 § 2.2.1][RFC 2.2.1].
        ///
        /// [RFC 2.2.1]: https://tools.ietf.org/html/rfc7049#section-2.2.1
        bitwidth: Option<IntegerWidth>,
    },

    /// Semantic tagging of another data item.
    ///
    /// See the docs for [`Tag`] for more details.
    Tag {
        /// The semantic tag to be applied to [`value`](#Tag.v.value.v).
        tag: Tag,

        /// The bitwidth used to encode the semantic tag.
        bitwidth: IntegerWidth,

        /// The data item which has the semantic tag applied to it.
        value: Box<DataItem>,
    },

    /// A floating point value.
    ///
    /// See [RFC 7049 § 2.3][RFC 2.3].
    ///
    /// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
    Float {
        /// The floating point value.
        value: f64,

        /// The bitwidth used for encoding the value.
        bitwidth: FloatWidth,
    },

    /// A "simple value" data item.
    ///
    /// See the docs for [`Simple`] for more details.
    Simple(Simple),
}

impl Simple {
    /// The simple value "False", equivalent to [`false`](bool).
    ///
    /// Defined in [RFC 7049 § 2.3: Table 2][RFC 2.3].
    ///
    /// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
    pub const FALSE: Simple = Simple(20);

    /// The simple value "True", equivalent to [`true`](bool).
    ///
    /// Defined in [RFC 7049 § 2.3: Table 2][RFC 2.3].
    ///
    /// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
    pub const TRUE: Simple = Simple(21);

    /// The simple value "Null", equivalent to a generic [`None`].
    ///
    /// Defined in [RFC 7049 § 2.3: Table 2][RFC 2.3].
    ///
    /// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
    pub const NULL: Simple = Simple(22);

    /// The simple value "Undefined value", not really equivalent to any Rust
    ///
    /// Defined in [RFC 7049 § 2.3: Table 2][RFC 2.3].
    ///
    /// [RFC 2.3]: https://tools.ietf.org/html/rfc7049#section-2.3
    /// concept.
    pub const UNDEFINED: Simple = Simple(23);
}