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
//! The four byte header that every value begins with, at every level.
//!
//! One word says what a value is and how big it is, and for a container it is
//! also the only thing a reader needs before it can index the entry table. It
//! is read unaligned, because a document is stored inside a record and a record
//! starts wherever the log put it.
/// What a value is, as a caller sees it.
///
/// The wire keeps object and array apart with a bit rather than a kind, since
/// they share a layout, but nobody outside this crate wants to write
/// `kind == Container && is_array()` so the two are separate here.
/// The wire tag, which is what the low three bits of a header hold.
///
/// The numbers are the format, so they are written out rather than derived from
/// declaration order, and 2 is missing on purpose: false and true are 1 and 3
/// so that the low bit of a boolean is the boolean.
pub
/// Set on a container that is an array, clear on one that is an object.
pub const ARRAY: u32 = 1 << 3;
/// Set on an object whose members are in key order, which is every object this
/// version writes. A reader that finds it clear falls back to a linear scan
/// rather than refusing the document, because an object out of order is still
/// readable and only a lookup gets slower.
pub const SORTED: u32 = 1 << 4;
/// Set on a container whose entry table carries offsets.
///
/// Every container this version writes has one, and a reader requires it. It is
/// here so that a later version can store lengths instead for a small container
/// and say so, which is the kind of change the format freeze has to leave room
/// for.
pub const OFFSETS: u32 = 1 << 5;
/// Set on an object whose keys are two byte ids from the collection's intern
/// table rather than bytes in a key region.
pub const INTERNED: u32 = 1 << 6;
/// Where the count starts.
pub const COUNT_SHIFT: u32 = 8;
/// The largest count a header can hold, which caps a container at 16.7 M
/// elements and a scalar at 16 MiB.
pub const COUNT_MAX: usize = - 1;
/// How deep a document may nest.
///
/// A reader walks a document with recursion, down the right hand edge to find a
/// length and down everything to check one, so the depth a writer will produce
/// and the depth a reader will accept have to be one number. It is the same
/// limit RedisJSON has, which means a document that was legal there stays legal
/// here.
pub const DEPTH_MAX: usize = 128;
/// A header built from its parts.
pub
/// The count a header carries: how many elements a container holds, and how
/// many bytes of payload a scalar has.
pub
/// The four bytes at `at`, or `None` if they are not all there.
pub