1#![cfg_attr(not(feature = "std"), no_std)]
127#![deny(missing_docs)]
128#![deny(clippy::all)]
129#![deny(clippy::cargo)]
130
131#[cfg(feature = "alloc")]
132extern crate alloc;
133
134mod dec;
135mod enc;
136mod hdr;
137mod seg;
138
139pub use dec::*;
140pub use enc::*;
141pub use hdr::*;
142pub use seg::{Segment, Segments};
143
144pub mod simple {
146 #![allow(missing_docs)]
147
148 pub const FALSE: u8 = 20;
149 pub const TRUE: u8 = 21;
150 pub const NULL: u8 = 22;
151 pub const UNDEFINED: u8 = 23;
152}
153
154pub mod tag {
156 #![allow(missing_docs)]
157
158 pub const BIGPOS: u64 = 2;
159 pub const BIGNEG: u64 = 3;
160}
161
162#[derive(Debug)]
163struct InvalidError(());
164
165#[derive(Copy, Clone, Debug, PartialEq, Eq)]
166enum Major {
167 Positive,
168 Negative,
169 Bytes,
170 Text,
171 Array,
172 Map,
173 Tag,
174 Other,
175}
176
177#[derive(Copy, Clone, Debug, PartialEq, Eq)]
178enum Minor {
179 This(u8),
180 Next1([u8; 1]),
181 Next2([u8; 2]),
182 Next4([u8; 4]),
183 Next8([u8; 8]),
184 More,
185}
186
187impl AsRef<[u8]> for Minor {
188 #[inline]
189 fn as_ref(&self) -> &[u8] {
190 match self {
191 Self::More => &[],
192 Self::This(..) => &[],
193 Self::Next1(x) => x.as_ref(),
194 Self::Next2(x) => x.as_ref(),
195 Self::Next4(x) => x.as_ref(),
196 Self::Next8(x) => x.as_ref(),
197 }
198 }
199}
200
201impl AsMut<[u8]> for Minor {
202 #[inline]
203 fn as_mut(&mut self) -> &mut [u8] {
204 match self {
205 Self::More => &mut [],
206 Self::This(..) => &mut [],
207 Self::Next1(x) => x.as_mut(),
208 Self::Next2(x) => x.as_mut(),
209 Self::Next4(x) => x.as_mut(),
210 Self::Next8(x) => x.as_mut(),
211 }
212 }
213}
214
215#[derive(Copy, Clone, Debug, PartialEq, Eq)]
216struct Title(pub Major, pub Minor);
217
218#[cfg(test)]
219mod tests {
220 use super::*;
221
222 macro_rules! neg {
223 ($i:expr) => {
224 Header::Negative((($i as i128) ^ !0) as u64)
225 };
226 }
227
228 #[allow(clippy::excessive_precision)]
229 #[test]
230 fn leaf() {
231 use core::f64::{INFINITY, NAN};
232
233 let data = &[
234 (Header::Positive(0), "00", true),
235 (Header::Positive(1), "01", true),
236 (Header::Positive(10), "0a", true),
237 (Header::Positive(23), "17", true),
238 (Header::Positive(24), "1818", true),
239 (Header::Positive(25), "1819", true),
240 (Header::Positive(100), "1864", true),
241 (Header::Positive(1000), "1903e8", true),
242 (Header::Positive(1000000), "1a000f4240", true),
243 (Header::Positive(1000000000000), "1b000000e8d4a51000", true),
244 (
245 Header::Positive(18446744073709551615),
246 "1bffffffffffffffff",
247 true,
248 ),
249 (neg!(-18446744073709551616), "3bffffffffffffffff", true),
250 (neg!(-1), "20", true),
251 (neg!(-10), "29", true),
252 (neg!(-100), "3863", true),
253 (neg!(-1000), "3903e7", true),
254 (Header::Float(0.0), "f90000", true),
255 (Header::Float(-0.0), "f98000", true),
256 (Header::Float(1.0), "f93c00", true),
257 (Header::Float(1.1), "fb3ff199999999999a", true),
258 (Header::Float(1.5), "f93e00", true),
259 (Header::Float(65504.0), "f97bff", true),
260 (Header::Float(100000.0), "fa47c35000", true),
261 (Header::Float(3.4028234663852886e+38), "fa7f7fffff", true),
262 (Header::Float(1.0e+300), "fb7e37e43c8800759c", true),
263 (Header::Float(5.960464477539063e-8), "f90001", true),
264 (Header::Float(0.00006103515625), "f90400", true),
265 (Header::Float(-4.0), "f9c400", true),
266 (Header::Float(-4.1), "fbc010666666666666", true),
267 (Header::Float(INFINITY), "f97c00", true),
268 (Header::Float(NAN), "f97e00", true),
269 (Header::Float(-INFINITY), "f9fc00", true),
270 (Header::Float(INFINITY), "fa7f800000", false),
271 (Header::Float(NAN), "fa7fc00000", false),
272 (Header::Float(-INFINITY), "faff800000", false),
273 (Header::Float(INFINITY), "fb7ff0000000000000", false),
274 (Header::Float(NAN), "fb7ff8000000000000", false),
275 (Header::Float(-INFINITY), "fbfff0000000000000", false),
276 (Header::Simple(simple::FALSE), "f4", true),
277 (Header::Simple(simple::TRUE), "f5", true),
278 (Header::Simple(simple::NULL), "f6", true),
279 (Header::Simple(simple::UNDEFINED), "f7", true),
280 (Header::Simple(16), "f0", true),
281 (Header::Simple(24), "f818", true),
282 (Header::Simple(255), "f8ff", true),
283 (Header::Tag(0), "c0", true),
284 (Header::Tag(1), "c1", true),
285 (Header::Tag(23), "d7", true),
286 (Header::Tag(24), "d818", true),
287 (Header::Tag(32), "d820", true),
288 (Header::Bytes(Some(0)), "40", true),
289 (Header::Bytes(Some(4)), "44", true),
290 (Header::Text(Some(0)), "60", true),
291 (Header::Text(Some(4)), "64", true),
292 ];
293
294 for (header, bytes, encode) in data.iter().cloned() {
295 let bytes = hex::decode(bytes).unwrap();
296
297 let mut decoder = Decoder::from(&bytes[..]);
298 match (header, decoder.pull().unwrap()) {
299 (Header::Float(l), Header::Float(r)) if l.is_nan() && r.is_nan() => (),
301
302 (l, r) => assert_eq!(l, r),
304 }
305
306 if encode {
307 let mut buffer = [0u8; 1024];
308 let mut writer = &mut buffer[..];
309 let mut encoder = Encoder::from(&mut writer);
310 encoder.push(header).unwrap();
311
312 let len = writer.len();
313 assert_eq!(&bytes[..], &buffer[..1024 - len]);
314 }
315 }
316 }
317
318 #[test]
319 fn node() {
320 let data: &[(&str, &[Header])] = &[
321 ("80", &[Header::Array(Some(0))]),
322 (
323 "83010203",
324 &[
325 Header::Array(Some(3)),
326 Header::Positive(1),
327 Header::Positive(2),
328 Header::Positive(3),
329 ],
330 ),
331 (
332 "98190102030405060708090a0b0c0d0e0f101112131415161718181819",
333 &[
334 Header::Array(Some(25)),
335 Header::Positive(1),
336 Header::Positive(2),
337 Header::Positive(3),
338 Header::Positive(4),
339 Header::Positive(5),
340 Header::Positive(6),
341 Header::Positive(7),
342 Header::Positive(8),
343 Header::Positive(9),
344 Header::Positive(10),
345 Header::Positive(11),
346 Header::Positive(12),
347 Header::Positive(13),
348 Header::Positive(14),
349 Header::Positive(15),
350 Header::Positive(16),
351 Header::Positive(17),
352 Header::Positive(18),
353 Header::Positive(19),
354 Header::Positive(20),
355 Header::Positive(21),
356 Header::Positive(22),
357 Header::Positive(23),
358 Header::Positive(24),
359 Header::Positive(25),
360 ],
361 ),
362 ("a0", &[Header::Map(Some(0))]),
363 (
364 "a201020304",
365 &[
366 Header::Map(Some(2)),
367 Header::Positive(1),
368 Header::Positive(2),
369 Header::Positive(3),
370 Header::Positive(4),
371 ],
372 ),
373 ("9fff", &[Header::Array(None), Header::Break]),
374 (
375 "9f018202039f0405ffff",
376 &[
377 Header::Array(None),
378 Header::Positive(1),
379 Header::Array(Some(2)),
380 Header::Positive(2),
381 Header::Positive(3),
382 Header::Array(None),
383 Header::Positive(4),
384 Header::Positive(5),
385 Header::Break,
386 Header::Break,
387 ],
388 ),
389 (
390 "9f01820203820405ff",
391 &[
392 Header::Array(None),
393 Header::Positive(1),
394 Header::Array(Some(2)),
395 Header::Positive(2),
396 Header::Positive(3),
397 Header::Array(Some(2)),
398 Header::Positive(4),
399 Header::Positive(5),
400 Header::Break,
401 ],
402 ),
403 (
404 "83018202039f0405ff",
405 &[
406 Header::Array(Some(3)),
407 Header::Positive(1),
408 Header::Array(Some(2)),
409 Header::Positive(2),
410 Header::Positive(3),
411 Header::Array(None),
412 Header::Positive(4),
413 Header::Positive(5),
414 Header::Break,
415 ],
416 ),
417 (
418 "83019f0203ff820405",
419 &[
420 Header::Array(Some(3)),
421 Header::Positive(1),
422 Header::Array(None),
423 Header::Positive(2),
424 Header::Positive(3),
425 Header::Break,
426 Header::Array(Some(2)),
427 Header::Positive(4),
428 Header::Positive(5),
429 ],
430 ),
431 (
432 "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff",
433 &[
434 Header::Array(None),
435 Header::Positive(1),
436 Header::Positive(2),
437 Header::Positive(3),
438 Header::Positive(4),
439 Header::Positive(5),
440 Header::Positive(6),
441 Header::Positive(7),
442 Header::Positive(8),
443 Header::Positive(9),
444 Header::Positive(10),
445 Header::Positive(11),
446 Header::Positive(12),
447 Header::Positive(13),
448 Header::Positive(14),
449 Header::Positive(15),
450 Header::Positive(16),
451 Header::Positive(17),
452 Header::Positive(18),
453 Header::Positive(19),
454 Header::Positive(20),
455 Header::Positive(21),
456 Header::Positive(22),
457 Header::Positive(23),
458 Header::Positive(24),
459 Header::Positive(25),
460 Header::Break,
461 ],
462 ),
463 ];
464
465 for (bytes, headers) in data {
466 let bytes = hex::decode(bytes).unwrap();
467
468 let mut decoder = Decoder::from(&bytes[..]);
470 for header in headers.iter().cloned() {
471 assert_eq!(header, decoder.pull().unwrap());
472 }
473
474 let mut buffer = [0u8; 1024];
476 let mut writer = &mut buffer[..];
477 let mut encoder = Encoder::from(&mut writer);
478
479 for header in headers.iter().cloned() {
480 encoder.push(header).unwrap();
481 }
482
483 let len = writer.len();
484 assert_eq!(&bytes[..], &buffer[..1024 - len]);
485 }
486 }
487}