3 releases
0.1.2 | Jun 20, 2024 |
---|---|
0.1.1 | Mar 22, 2024 |
0.1.0 | Mar 22, 2024 |
#276 in No standard library
186 downloads per month
Used in cbor-macro
15KB
89 lines
cboritem
cboritem: A serialized CBOR item
A CborItem<'a>
is a newtype around &'a [u8]
that upholds the invariant of
containing a single serialized CBOR item. A ThinCborItem<'a>
is its start
pointer; when accessing it, users rely on that property to stop reading at the end of the item.
In a sense, the types are similar to &str
and CStr
, respectively,
once the latter follows the plan of eventually becoming a thin pointer.
Library use
Their use is for efficiently storing pre-verified slices of CBOR items, eg. when implementing packed CBOR. They can also serve as an interface point between CBOR libraries (easing error handling because end-of-stream and bytes-after-the-data errors are panic-worthy invariants; other parsing errors may still occur if there is any well-formed data the parser can not process, or that violates basic validity requirements), and as a marker type by which CBOR parsers can be instructed to process any item into a slice for later detailed inspection.
This crate is not a CBOR library, thus it contains no functions to safely create any of its types (as that requires a CBOR parser). Instead, its intention is to be produced by CBOR parsers after they have verified that the invariant upholds.
Invariant definition
The invariant upheld in this crate’s types is that their bytes are exactly one well-formed CBOR item as defined in RFC8949; in particular, that means they contain at least one byte.
The invariants in this crates are soundness invariants: Receivers of a CBOR item may not
just panic when they find invalid CBOR, but they may invoke undefined behavior (eg. by calling
unreachable_unchecked
. Consequently, creating a CBOR
item requires use of the unsafe
keyword, with the invariants being checked by the parser that
creates the item.
This is a necessary consequence of providing thin pointers: The invariants are relied on by users who read through a raw pointer, which on inaccurate data would result in reads beyond the original allocated object, which is undefined behavior.
Examples
use cboritem::{CborItem, ThinCborItem};
let onehundred = [0x24, 0x64];
assert_eq!(onehundred[0], 0x24);
let onehundred = unsafe { CborItem::new(&onehundred) };
let onehundred: ThinCborItem<'_> = onehundred.as_thin();
assert_eq!(core::mem::size_of_val(&onehundred), core::mem::size_of::<&u8>());
// One byte can always be read, so we don't need a CBOR parser to tell us it is safe
if onehundred.first() == 0x24 {
assert_eq!(unsafe { onehundred.offset(1).read() }, 100);
} else {
panic!("Unexpected type or integer size");
}
Future development
Later versions may add types or variants of the current types (by means of associated types with a default), eg. to descibe additional constraints such as
- Embedded strings are UTF-8
- No duplicate keys are present
- Adhers to the Common Deterministic Encoding
- Contains no indefinite-length items
- The CBOR item conforms to some particular CDDL structure
If any extensions are made that change CBOR’s validity rules (eg. i=28 is defined for 128-bit integer arguments), this crate would go through a major release to support them.