// SPDX-License-Identifier: Apache-2.0
//! Welcome to Ciborium!
//!
//! Ciborium contains CBOR serialization and deserialization implementations for serde.
//!
//! # Quick Start
//!
//! You're probably looking for [`de::from_reader()`](crate::de::from_reader)
//! and [`ser::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::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.
extern crate alloc;
/// Build a `Value` conveniently.
///
/// The syntax should be intuitive if you are familiar with JSON. You can also
/// inline simple Rust expressions, including custom values that implement
/// `serde::Serialize`. Note that this macro returns `Result<Value, Error>`,
/// so you should handle the error appropriately.
///
/// ```
/// use ciboriumvalue::cbor;
///
/// let value = cbor!({
/// "code" => 415,
/// "message" => null,
/// "continue" => false,
/// "extra" => { "numbers" => [8.2341e+4, 0.251425] },
/// }).unwrap();
/// ```