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
//! Canonical profile definition for SACP-CBOR/1.
//!
//! A byte sequence is **canonical for this crate** iff:
//!
//! - It encodes exactly one CBOR data item (no trailing bytes).
//! - Definite lengths only (no indefinite-length encodings).
//! - Integers:
//! - Major types 0/1 are restricted to safe integers in
//! `[-(2^53-1), +(2^53-1)]`.
//! - Larger integers must be tags 2/3 bignums with canonical magnitudes:
//! non-empty, no leading zero, and *outside* the safe range in the correct direction.
//! - Bytes (major 2): definite length.
//! - Text (major 3): definite length, valid UTF-8.
//! - Arrays/maps (majors 4/5): definite length.
//! - Maps: keys are text strings, canonical order, and unique.
//! - Simple values: only `false`, `true`, `null` (major 7, ai 20..=22).
//! - Floats: only float64 (major 7, ai=27), forbid negative zero, and require the
//! canonical NaN bit pattern.
//!
//! **Canonical map order** compares the *encoded key bytes* by:
//! 1) encoded length (shorter first), then
//! 2) lexicographic byte order.
//!
//! For canonical text keys, this is equivalent to comparing `(payload_len, payload_bytes)` because
//! the canonical header length is a strictly monotone function of the payload length.
//!
//! ## Trust boundary
//! [`CborBytesRef`](crate::CborBytesRef) is the only public witness that a byte slice is canonical.
//! All canonical-trusted parsing (query/edit/serde trusted mode) assumes this witness was produced
//! by [`validate_canonical`](crate::validate_canonical) or constructed internally.
use Ordering;
use crateErrorCode;
/// Maximum safe integer (2^53-1).
///
/// SACP-CBOR/1 permits major-type integers only in the safe range
/// `[-(2^53-1), +(2^53-1)]`.
pub const MAX_SAFE_INTEGER: u64 = 9_007_199_254_740_991;
/// Maximum safe integer as i64 (2^53-1).
pub const MAX_SAFE_INTEGER_I64: i64 = 9_007_199_254_740_991;
/// Minimum safe integer (-(2^53-1)).
pub const MIN_SAFE_INTEGER: i64 = -MAX_SAFE_INTEGER_I64;
/// Canonical big-endian bytes of `MAX_SAFE_INTEGER` (2^53-1) with leading zeros stripped.
///
/// 2^53-1 = `0x001f_ffff_ffff_ffff`, so the canonical magnitude is 7 bytes:
/// `1f ff ff ff ff ff ff`.
const MAX_SAFE_INTEGER_BE: = ;
/// Canonical NaN bit pattern for SACP-CBOR/1 float64.
pub const CANONICAL_NAN_BITS: u64 = 0x7ff8_0000_0000_0000;
/// Negative zero bit pattern (forbidden).
pub const NEGATIVE_ZERO_BITS: u64 = 0x8000_0000_0000_0000;
const EXP_MASK: u64 = 0x7ff0_0000_0000_0000;
const MANT_MASK: u64 = 0x000f_ffff_ffff_ffff;
/// Validate an IEEE-754 f64 bit pattern for SACP-CBOR/1.
pub const
/// Validate that an i64 is within the SACP-CBOR/1 safe integer range.
pub const
/// Validate that a bignum magnitude is canonical and outside the safe range.
/// Compare two CBOR-encoded map keys by the canonical CBOR ordering rule.
///
/// Canonical ordering is:
/// 1) shorter encoded byte string sorts first, then
/// 2) lexicographic byte comparison.
///
/// This is used by the validator when it already has the encoded key slices. For text keys, this
/// matches [`cmp_text_keys_canonical`] on the decoded strings.
/// Compare two UTF-8 text keys by SACP-CBOR/1 canonical map ordering.
///
/// For SACP-CBOR/1 maps, keys are restricted to CBOR text strings. Canonical map ordering is defined
/// over the *canonical CBOR encoding* of each key:
///
/// 1) shorter encoded key sorts first (this includes the header bytes), then
/// 2) lexicographic ordering of the encoded key bytes.
///
/// For text strings, the encoded length is strictly monotone in payload length, so the ordering is
/// exactly the same as comparing payload lengths and then the UTF-8 bytes.
/// Return the length in bytes of the canonical CBOR encoding of a text string payload of length `n`.
///
/// This is `header_len(n) + n`, where `header_len(n)` depends on the canonical CBOR length encoding:
///
/// - `n < 24` => 1-byte header
/// - `n <= 255` => 2-byte header
/// - `n <= 65535` => 3-byte header
/// - `n <= 2^32-1` => 5-byte header
/// - otherwise => 9-byte header