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