|  | [](https://github.com/enarx/ciborium/actions?query=workflow%3A%22test%22) | 
|  | [](https://isitmaintained.com/project/enarx/ciborium "Average time to resolve an issue") | 
|  | [](https://isitmaintained.com/project/enarx/ciborium "Percentage of issues still open") | 
|  |  | 
|  |  | 
|  | # ciborium | 
|  |  | 
|  | Welcome to Ciborium! | 
|  |  | 
|  | Ciborium contains CBOR serialization and deserialization implementations for serde. | 
|  |  | 
|  | ## Quick Start | 
|  |  | 
|  | You're probably looking for [`from_reader()`](crate::de::from_reader) | 
|  | and [`into_writer()`](crate::ser::into_writer), which are | 
|  | the main functions. Note that byte slices are also readers and writers and can be | 
|  | passed to these functions just as streams can. | 
|  |  | 
|  | For dynamic CBOR value creation/inspection, see [`Value`](crate::value::Value). | 
|  |  | 
|  | ## Design Decisions | 
|  |  | 
|  | ### Always Serialize Numeric Values to the Smallest Size | 
|  |  | 
|  | Although the CBOR specification has differing numeric widths, this is only | 
|  | a form of compression on the wire and is not intended to directly | 
|  | represent an "integer width" or "float width." Therefore, ciborium always | 
|  | serializes numbers to the smallest possible lossless encoding. For example, | 
|  | we serialize `1u128` as a single byte (`01`). Likewise, we will also freely | 
|  | decode that single byte into a `u128`. | 
|  |  | 
|  | While there is some minor performance cost for this, there are several | 
|  | reasons for this choice. First, the specification seems to imply it by | 
|  | using a separate bit for the sign. Second, the specification requires | 
|  | that implementations handle leading zeroes; a liberal reading of which | 
|  | implies a requirement for lossless coercion. Third, dynamic languages like | 
|  | Python have no notion of "integer width," making this is a practical | 
|  | choice for maximizing wire compatibility with those languages. | 
|  |  | 
|  | This coercion is **always** lossless. For floats, this implies that we | 
|  | only coerce to a smaller size if coercion back to the original size has | 
|  | the same raw bits as the original. | 
|  |  | 
|  | ### Compatibility with Other Implementations | 
|  |  | 
|  | The ciborium project follows the [Robustness Principle](https://en.wikipedia.org/wiki/Robustness_principle). | 
|  | Therefore, we aim to be liberal in what we accept. This implies that we | 
|  | aim to be wire-compatible with other implementations in decoding, but | 
|  | not necessarily encoding. | 
|  |  | 
|  | One notable example of this is that `serde_cbor` uses fixed-width encoding | 
|  | of numbers and doesn't losslessly coerce. This implies that `ciborium` will | 
|  | successfully decode `serde_cbor` encodings, but the opposite may not be the | 
|  | case. | 
|  |  | 
|  | ### Representing Map as a Sequence of Values | 
|  |  | 
|  | Other serde parsers have generally taken the route of using `BTreeMap` or | 
|  | `HashMap` to implement their encoding's underlying `Map` type. This crate | 
|  | chooses to represent the `Map` type using `Vec<(Value, Value)>` instead. | 
|  |  | 
|  | This decision was made because this type preserves the order of the pairs | 
|  | on the wire. Further, for those that need the properties of `BTreeMap` or | 
|  | `HashMap`, you can simply `collect()` the values into the respective type. | 
|  | This provides maximum flexibility. | 
|  |  | 
|  | ### Low-level Library | 
|  |  | 
|  | The ciborium crate has the beginnings of a low-level library in the | 
|  | (private) `basic` module. We may extend this to be more robust and expose | 
|  | it for application consumption once we have it in a good state. If you'd | 
|  | like to collaborate with us on that, please contact us. Alternatively, | 
|  | we might fork this code into a separate crate with no serde dependency. | 
|  |  | 
|  | ### Internal Types | 
|  |  | 
|  | The ciborium crate contains a number of internal types that implement | 
|  | useful serde traits. While these are not currently exposed, we might | 
|  | choose to expose them in the future if there is demand. Generally, this | 
|  | crate takes a conservative approach to exposing APIs to avoid breakage. | 
|  |  | 
|  | ### Packed Encoding? | 
|  |  | 
|  | Packed encoding uses numerical offsets to represent structure field names | 
|  | and enum variant names. This can save significant space on the wire. | 
|  |  | 
|  | While the authors of this crate like packed encoding, it should generally | 
|  | be avoided because it can be fragile as it exposes invariants of your Rust | 
|  | code to remote actors. We might consider adding this in the future. If you | 
|  | are interested in this, please contact us. | 
|  |  | 
|  | License: Apache-2.0 |