• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[![Workflow Status](https://github.com/enarx/ciborium/workflows/test/badge.svg)](https://github.com/enarx/ciborium/actions?query=workflow%3A%22test%22)
2[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/enarx/ciborium.svg)](https://isitmaintained.com/project/enarx/ciborium "Average time to resolve an issue")
3[![Percentage of issues still open](https://isitmaintained.com/badge/open/enarx/ciborium.svg)](https://isitmaintained.com/project/enarx/ciborium "Percentage of issues still open")
4![Maintenance](https://img.shields.io/badge/maintenance-activly--developed-brightgreen.svg)
5
6# ciborium
7
8Welcome to Ciborium!
9
10Ciborium contains CBOR serialization and deserialization implementations for serde.
11
12## Quick Start
13
14You're probably looking for [`de::from_reader()`](crate::de::from_reader)
15and [`ser::into_writer()`](crate::ser::into_writer), which are
16the main functions. Note that byte slices are also readers and writers and can be
17passed to these functions just as streams can.
18
19For dynamic CBOR value creation/inspection, see [`value::Value`](crate::value::Value).
20
21## Design Decisions
22
23### Always Serialize Numeric Values to the Smallest Size
24
25Although the CBOR specification has differing numeric widths, this is only
26a form of compression on the wire and is not intended to directly
27represent an "integer width" or "float width." Therefore, ciborium always
28serializes numbers to the smallest possible lossless encoding. For example,
29we serialize `1u128` as a single byte (`01`). Likewise, we will also freely
30decode that single byte into a `u128`.
31
32While there is some minor performance cost for this, there are several
33reasons for this choice. First, the specification seems to imply it by
34using a separate bit for the sign. Second, the specification requires
35that implementations handle leading zeroes; a liberal reading of which
36implies a requirement for lossless coercion. Third, dynamic languages like
37Python have no notion of "integer width," making this is a practical
38choice for maximizing wire compatibility with those languages.
39
40This coercion is **always** lossless. For floats, this implies that we
41only coerce to a smaller size if coercion back to the original size has
42the same raw bits as the original.
43
44### Compatibility with Other Implementations
45
46The ciborium project follows the [Robustness Principle](https://en.wikipedia.org/wiki/Robustness_principle).
47Therefore, we aim to be liberal in what we accept. This implies that we
48aim to be wire-compatible with other implementations in decoding, but
49not necessarily encoding.
50
51One notable example of this is that `serde_cbor` uses fixed-width encoding
52of numbers and doesn't losslessly coerce. This implies that `ciborium` will
53successfully decode `serde_cbor` encodings, but the opposite may not be the
54case.
55
56### Representing Map as a Sequence of Values
57
58Other serde parsers have generally taken the route of using `BTreeMap` or
59`HashMap` to implement their encoding's underlying `Map` type. This crate
60chooses to represent the `Map` type using `Vec<(Value, Value)>` instead.
61
62This decision was made because this type preserves the order of the pairs
63on the wire. Further, for those that need the properties of `BTreeMap` or
64`HashMap`, you can simply `collect()` the values into the respective type.
65This provides maximum flexibility.
66
67### Low-level Library
68
69The ciborium crate has the beginnings of a low-level library in the
70(private) `basic` module. We may extend this to be more robust and expose
71it for application consumption once we have it in a good state. If you'd
72like to collaborate with us on that, please contact us. Alternatively,
73we might fork this code into a separate crate with no serde dependency.
74
75### Internal Types
76
77The ciborium crate contains a number of internal types that implement
78useful serde traits. While these are not currently exposed, we might
79choose to expose them in the future if there is demand. Generally, this
80crate takes a conservative approach to exposing APIs to avoid breakage.
81
82### Packed Encoding?
83
84Packed encoding uses numerical offsets to represent structure field names
85and enum variant names. This can save significant space on the wire.
86
87While the authors of this crate like packed encoding, it should generally
88be avoided because it can be fragile as it exposes invariants of your Rust
89code to remote actors. We might consider adding this in the future. If you
90are interested in this, please contact us.
91
92License: Apache-2.0
93