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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
//! The two things every BEVE value is built from: a header byte and a
//! compressed size.
//!
//! Both are small enough that they are given as `const fn`s, which lets the
//! [`object!`](crate::object) macro assemble a struct's key encodings during
//! const evaluation and lets every header used by the impls fold to a literal.
//!
//! # Header layout
//!
//! ```text
//! bit 7 6 5 4 3 2 1 0
//! [ count ][ sub ][ ty ]
//! ```
//!
//! `ty` is the value's kind, `sub` narrows it (a number's signedness, an
//! object's key type, an array's element category), and `count` is the
//! [byte-count code](byte_width): the element width is `1 << count`, with
//! floats the one documented exception.
use crate;
// --- Types (bits 0-2) ------------------------------------------------------
pub const TY_NULL_BOOL: u8 = 0;
pub const TY_NUMBER: u8 = 1;
pub const TY_STRING: u8 = 2;
pub const TY_OBJECT: u8 = 3;
pub const TY_TYPED_ARRAY: u8 = 4;
pub const TY_GENERIC_ARRAY: u8 = 5;
pub const TY_EXTENSION: u8 = 6;
/// The one type code the specification leaves undefined.
///
/// The field is three bits wide and six values are spoken for, so this is the
/// only bit pattern that can stand for something which is not a value at all.
/// [`complex_element`] is the one thing that needs such a code, and no document
/// may carry it: a header read out of the input with this type is refused.
pub const TY_UNDEFINED: u8 = 7;
// --- Sub-types (bits 3-4) --------------------------------------------------
/// Number and typed-array element categories, and object key types. The three
/// share an encoding, which is what lets a typed array's header become its
/// element's header by swapping the type bits alone.
pub const CAT_FLOAT: u8 = 0;
pub const CAT_SIGNED: u8 = 1;
pub const CAT_UNSIGNED: u8 = 2;
/// Typed arrays only: booleans, strings, or an aligned numeric block, told
/// apart by the byte-count field.
pub const CAT_OTHER: u8 = 3;
/// Byte-count values under [`CAT_OTHER`].
pub const OTHER_BOOL: u8 = 0;
pub const OTHER_STRING: u8 = 1;
pub const OTHER_ALIGNED: u8 = 2;
// --- Extension ids (bits 3-7) ----------------------------------------------
pub const EXT_DELIMITER: u8 = 0;
pub const EXT_TYPE_TAG: u8 = 1;
pub const EXT_MATRIX: u8 = 2;
pub const EXT_COMPLEX: u8 = 3;
// --- Whole headers ---------------------------------------------------------
/// Assemble a header from its three fields.
pub const
pub const NULL: u8 = 0;
pub const FALSE: u8 = 0b0000_1000;
pub const TRUE: u8 = 0b0001_1000;
pub const STRING: u8 = TY_STRING;
pub const GENERIC_ARRAY: u8 = TY_GENERIC_ARRAY;
/// An object with string keys, which is what every `object!` struct is.
pub const OBJECT: u8 = TY_OBJECT;
/// The delimiter extension: a marker with no body, which the specification
/// offers for separating documents in a stream. Assembled by hand because an
/// extension carries its id in the five bits above the type rather than in the
/// `sub` and `count` fields [`header`] takes.
///
/// It separates values and is never one. Between documents,
/// [`Documents::values`](crate::beve::Documents::values) steps over it; where a
/// value belongs, every walk that takes whatever value is there refuses it as
/// [`InvalidHeader`](ErrorCode::InvalidHeader): validating, skipping, reading a
/// [`Value`](crate::Value), transcoding and framing alike. Not
/// [`UnsupportedFeature`](ErrorCode::UnsupportedFeature), which promises a
/// well-formed construct this crate merely declines, where a document holding
/// a delimiter in a value's place holds no value there at all. Had any one walk
/// stepped over it as a value of no extent, the validator would pass a document
/// that frames as nothing and that no reader can read.
///
/// A typed read that wanted a particular kind reports the mismatch instead,
/// `ExpectedNumber` and the like, as it does for any header that is not what
/// it wanted.
pub const DELIMITER: u8 = TY_EXTENSION | ;
/// The matrix extension: a layout byte, then the extents and the data, each a
/// value of its own.
pub const MATRIX: u8 = TY_EXTENSION | ;
/// The complex extension, which a [class header](complex_class) always follows.
pub const COMPLEX: u8 = TY_EXTENSION | ;
/// The number header for a `count`-coded value of `cat`.
pub const
/// The typed-array header for elements of `cat` at width code `count`.
pub const
pub const BOOL_ARRAY: u8 = array_of;
pub const STRING_ARRAY: u8 = array_of;
pub const ALIGNED_ARRAY: u8 = array_of;
// --- Extension bodies -----------------------------------------------------
/// A matrix stored with its rightmost index varying fastest: row major.
pub const LAYOUT_RIGHT: u8 = 0;
/// A matrix stored with its leftmost index varying fastest: column major.
pub const LAYOUT_LEFT: u8 = 1;
/// A lone complex number: the class header is followed by one pair.
pub const COMPLEX_ONE: u8 = 0;
/// A run of complex numbers: a size stands between the class header and the
/// pairs.
pub const COMPLEX_MANY: u8 = 1;
/// A run of complex numbers whose components are an
/// [aligned](ALIGNED_ARRAY) typed array: the class header is followed by that
/// whole array, `2 * N` components long, of the class's own type.
pub const COMPLEX_ALIGNED: u8 = 2;
/// The class header a complex value carries, in the byte after
/// [`COMPLEX`].
///
/// The class and byte-count fields sit exactly where [`number`] puts them, so
/// the width of a complex component is read by the same [`byte_width`]. What
/// differs is the low three bits: a number header spends them on its type,
/// this one on [`COMPLEX_ONE`], [`COMPLEX_MANY`] or [`COMPLEX_ALIGNED`]. The
/// field is three bits wide for that alignment and no other reason, and the
/// other five values are undefined; a reader must refuse them rather than
/// guess, because the three defined forms differ by what precedes the payload.
pub const
/// The typed-array header an [aligned complex array](COMPLEX_ALIGNED) stores
/// its components under, which is the class with the form swapped for the
/// typed-array type.
///
/// Exactly this byte and no other: the specification requires the inner
/// array's element type and width to be the class's, and the class's width
/// has been checked by the time anything asks.
pub const
/// The header a complex array's elements are matched against.
///
/// Synthetic, and by construction not a byte any document can hold. A complex
/// element carries no header at all, so something has to stand for one, and the
/// obvious candidate is unusable: a class header of form [`COMPLEX_MANY`] is
/// bit for bit the [`number`] header of the same class and width, `0x61` being
/// both a complex array of `f64` and a lone `f64`. This is [`element_of`] with
/// [`TY_UNDEFINED`] in place of the type, which keeps the class and the width
/// where every reader already looks for them and leaves a byte equal to nothing
/// else at all. So a `Vec<f64>` cannot bulk-read the payload of a complex
/// array, and nothing has to ask where a header came from to know what it is.
pub const
pub const
pub const
pub const
pub const
/// Turn a typed array's header into the header its elements would carry if
/// they were written as standalone values.
///
/// The category and width fields already line up; only the type changes. For
/// [`CAT_OTHER`] arrays the result is meaningless and the caller must not ask.
pub const
/// Bytes one element carrying `elem` occupies in a block's payload.
///
/// `elem` is an *element* header, which is either a [`number`]'s -- the form
/// [`element_of`] produces for every numeric typed array -- or the synthetic
/// one [`complex_element`] produces, where the same class and width fields
/// describe a component and an element is two of them. `None` for anything
/// else, a header with no width being one no block is measured by.
///
/// Internal, and shared by the three places that have to agree on it: the
/// width a [`NumericBytes`](crate::beve::NumericBytes) type is pinned against,
/// the stride the splitter cuts a block into, and the walk that steps over a
/// complex element. A caller holding the components' width already, as the
/// complex-array head parser does, doubles it rather than deriving it again.
pub const
/// The byte-count code for a `width`-byte value.
///
/// The inverse of `1 << count`, which is the rule for every width this crate
/// writes. It is not used for the two 16-bit floats, whose codes do not follow
/// that rule; see [`byte_width`].
pub const
/// Bytes one element of category `cat` at width code `count` occupies.
///
/// The integer categories follow `1 << count` exactly. Floats do not: BEVE has
/// no 8-bit float, so code 0 is `bfloat16` and code 1 is `float16`, both two
/// bytes wide. Every width calculation goes through here so that exception
/// cannot be forgotten at one call site and honoured at another.
pub const
/// [`byte_width`] for a walk that decodes the number rather than stepping over
/// it.
///
/// A width the format does not define is
/// [`InvalidHeader`](ErrorCode::InvalidHeader), as it is to every walk. A
/// 128-bit float is well formed and has no Rust type to land in, so it is
/// [`UnsupportedFeature`](ErrorCode::UnsupportedFeature) here, where a walk
/// that only measures it steps over it. Both are known from the header, so a
/// decoding walk asks this before it takes the payload, and every one of them
/// stops in the same place.
pub const
// --- Compressed unsigned integers ------------------------------------------
/// Largest size the codec can express: 2^62 - 1.
pub const MAX_SIZE: u64 = - 1;
/// Bytes [`encode_size`] emits for `n`.
///
/// The thresholds live here alone, so a length computed ahead of time cannot
/// disagree with the bytes actually written.
pub const
/// Encode `n` into `out`, returning the number of bytes used.
///
/// The low two bits of the first byte select the total width; the value fills
/// the remaining bits, little end first.
///
/// # Panics
///
/// If `n > MAX_SIZE`, which no size derived from a real collection can reach:
/// 2^62 elements do not fit in an address space.
pub const
const
/// Bytes of a compressed size that follow its first one.
///
/// The width lives in the low two bits, and this is the only place that reads
/// them: a stream has to decode a size a byte at a time rather than out of a
/// slice, and two copies of this table are two things that could disagree
/// about where a value ends.
pub const
/// Decode a compressed size from `data` at `*pos`, advancing past it.
// --- Object keys -----------------------------------------------------------
/// Bytes a struct key occupies on the wire: its size prefix plus its text.
///
/// An object key carries no header, because the object's own header already
/// said the keys are strings.
pub const
/// The complete `SIZE | DATA` encoding of a struct key.
///
/// `N` must be [`key_len`] of the same key; the macro derives it from exactly
/// that call. Assembling the two halves at compile time makes writing a member
/// one copy of one constant, the same trick the JSON side plays with its
/// pre-quoted `"key":` prefix.
pub const