summaryrefslogtreecommitdiffstats
path: root/vendor/ciborium/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ciborium/src/lib.rs')
-rw-r--r--vendor/ciborium/src/lib.rs222
1 files changed, 222 insertions, 0 deletions
diff --git a/vendor/ciborium/src/lib.rs b/vendor/ciborium/src/lib.rs
new file mode 100644
index 000000000..9696e5ffa
--- /dev/null
+++ b/vendor/ciborium/src/lib.rs
@@ -0,0 +1,222 @@
+// 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 [`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.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![deny(missing_docs)]
+#![deny(clippy::all)]
+#![deny(clippy::cargo)]
+#![allow(clippy::unit_arg)]
+
+extern crate alloc;
+
+pub mod de;
+pub mod ser;
+pub mod tag;
+pub mod value;
+
+// Re-export the [items recommended by serde](https://serde.rs/conventions.html).
+#[doc(inline)]
+pub use crate::de::from_reader;
+
+#[doc(inline)]
+pub use crate::ser::into_writer;
+
+#[doc(inline)]
+pub use crate::value::Value;
+
+/// 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 ciborium::cbor;
+///
+/// let value = cbor!({
+/// "code" => 415,
+/// "message" => null,
+/// "continue" => false,
+/// "extra" => { "numbers" => [8.2341e+4, 0.251425] },
+/// }).unwrap();
+/// ```
+#[macro_export]
+macro_rules! cbor {
+ (@map {$($key:expr => $val:expr),*} $(,)?) => {{
+ $crate::value::Value::Map(vec![
+ $(
+ (cbor!( $key )?, cbor!( $val )?)
+ ),*
+ ])
+ }};
+
+ (@map {$($key:expr => $val:expr),*} { $($nkey:tt)* } => $($next:tt)*) => {
+ cbor!(
+ @map
+ { $($key => $val),* }
+ cbor!({ $($nkey)* })? =>
+ $($next)*
+ )
+ };
+
+ (@map {$($key:expr => $val:expr),*} [ $($nkey:tt)* ] => $($next:tt)*) => {
+ cbor!(
+ @map
+ { $($key => $val),* }
+ cbor!([ $($nkey)* ])? =>
+ $($next)*
+ )
+ };
+
+ (@map {$($key:expr => $val:expr),*} $nkey:expr => { $($nval:tt)* }, $($next:tt)*) => {
+ cbor!(
+ @map
+ { $($key => $val,)* $nkey => cbor!({ $($nval)* })? }
+ $($next)*
+ )
+ };
+
+ (@map {$($key:expr => $val:expr),*} $nkey:expr => [ $($nval:tt)* ], $($next:tt)*) => {
+ cbor!(
+ @map
+ { $($key => $val,)* $nkey => cbor!([ $($nval)* ])? }
+ $($next)*
+ )
+ };
+
+ (@map {$($key:expr => $val:expr),*} $nkey:expr => $nval:expr, $($next:tt)*) => {
+ cbor!(
+ @map
+ { $($key => $val,)* $nkey => cbor!($nval)? }
+ $($next)*
+ )
+ };
+
+ (@seq [$($val:expr),*] $(,)?) => {
+ $crate::value::Value::Array(
+ vec![$( cbor!($val)? ),*]
+ )
+ };
+
+ (@seq [$($val:expr),*] { $($item:tt)* }, $($next:tt)*) => {
+ cbor!(
+ @seq
+ [ $($val,)* cbor!({ $($item)* })? ]
+ $($next)*
+ )
+ };
+
+ (@seq [$($val:expr),*] [ $($item:tt)* ], $($next:tt)*) => {
+ cbor!(
+ @seq
+ [ $($val,)* cbor!([ $($item)* ])? ]
+ $($next)*
+ )
+ };
+
+ (@seq [$($val:expr),*] $item:expr, $($next:tt)*) => {
+ cbor!(
+ @seq
+ [ $($val,)* $item ]
+ $($next)*
+ )
+ };
+
+ ({ $($next:tt)* }) => {(||{
+ ::core::result::Result::<_, $crate::value::Error>::from(Ok(cbor!(@map {} $($next)* ,)))
+ })()};
+
+ ([ $($next:tt)* ]) => {(||{
+ ::core::result::Result::<_, $crate::value::Error>::from(Ok(cbor!(@seq [] $($next)* ,)))
+ })()};
+
+ ($val:expr) => {{
+ #[allow(unused_imports)]
+ use $crate::value::Value::Null as null;
+ $crate::value::Value::serialized(&$val)
+ }};
+}