deser_cbor/lib.rs
1//! Parse and serialize [CBOR](https://www.rfc-editor.org/rfc/rfc8949) compatible
2//! with deser.
3//!
4//! ```rust
5//! let bytes = deser_cbor::to_vec(&vec![1u64, 2, 3, 4]).unwrap();
6//! assert_eq!(bytes, [0x84, 0x01, 0x02, 0x03, 0x04]);
7//! let vec: Vec<u64> = deser_cbor::from_slice(&bytes).unwrap();
8//! assert_eq!(vec, [1, 2, 3, 4]);
9//! ```
10//!
11//! # Data Model
12//!
13//! The deser data model maps onto CBOR as follows:
14//!
15//! | deser | CBOR |
16//! |-------------------------|---------------------------------------------------|
17//! | `Null` | `null` (`undefined` is also read as `Null`) |
18//! | `Bool` | `false` / `true` |
19//! | `U64`, `I64` | unsigned and negative integers |
20//! | `u128`, `i128` | integers or bignums (tags 2 and 3) |
21//! | [`BigInt`] | bignums (tags 2 and 3) |
22//! | [`Datetime`] | date/time (tag 0), full-date (tag 1004) or text |
23//! | [`Timestamp`] | epoch date/time (tag 1) or date/time (tag 0) |
24//! | [`Uuid`] | UUIDs (tag 37) |
25//! | [`Decimal`] | decimal fractions (tag 4) |
26//! | `F32`, `F64` | half, single or double precision floats |
27//! | `Str`, `Char` | text strings |
28//! | `Bytes` | byte strings |
29//! | maps and sequences | maps and arrays |
30//! | [`Simple`] | unassigned simple values |
31//!
32//! Offset date-times are written with tag 0, local dates with tag 1004 and
33//! other date-times as plain text strings. Timestamps are written with tag
34//! 1 unless they have a fraction of a second, then they are written as
35//! date/time string (tag 0) which retains the precision. Other extension
36//! values (such as [`Duration`](deser_core::ext::Duration)) are written as their
37//! fallback.
38//!
39//! Serialization produces the preferred serialization of RFC 8949: the
40//! shortest form is used for integers and lengths, floats are written in the
41//! shortest form that preserves their value and all maps and arrays have a
42//! definite length. With [`SerializerConfig::set_canonical`] map entries are
43//! additionally sorted to produce a deterministic encoding.
44//!
45//! Deserialization accepts all well-formed CBOR including indefinite length
46//! strings, arrays and maps. Map keys can be of any type. Integers that
47//! do not fit into 64 bits are passed on as `u128` / `i128` extension atoms
48//! and larger ones as [`BigInt`]. The tags 0, 4, 37 and 1004 are turned
49//! into the well-known types [`Datetime`], [`Decimal`] and [`Uuid`] if their
50//! content is valid. Epoch based date/times (tag 1) are passed on as tagged
51//! numbers, [`Timestamp`] accepts them. All floats are read as `F64`: RFC
52//! 8949 does not distinguish the precisions in the data model, the shortest
53//! one that preserves the value is picked when writing.
54//!
55//! [`BigInt`]: deser_core::ext::BigInt
56//! [`Datetime`]: deser_core::ext::Datetime
57//! [`Timestamp`]: deser_core::ext::Timestamp
58//! [`Uuid`]: deser_core::ext::Uuid
59//! [`Decimal`]: deser_core::ext::Decimal
60//!
61//! # Raw Values
62//!
63//! [`RawCbor`] holds the CBOR encoding of a value. The encoding of values
64//! that are deserialized from CBOR is kept as it is (including tags and
65//! how lengths and integers were encoded): it's validated but not
66//! deserialized, and written out again unchanged unless canonical output is
67//! requested. Values of other formats are encoded as CBOR.
68//!
69//! ```rust
70//! use deser_cbor::RawCbor;
71//!
72//! #[derive(deser::Deserialize, deser::Serialize)]
73//! struct Record {
74//! id: u32,
75//! payload: RawCbor<'static>,
76//! }
77//!
78//! // {"id": 1, "payload": [_ 1, 2]}
79//! let input = [
80//! 0xa2, 0x62, b'i', b'd', 0x01, 0x67, b'p', b'a', b'y', b'l', b'o',
81//! b'a', b'd', 0x9f, 0x01, 0x02, 0xff,
82//! ];
83//! let record: Record = deser_cbor::from_slice(&input).unwrap();
84//! assert_eq!(record.payload.as_bytes(), [0x9f, 0x01, 0x02, 0xff]);
85//! assert_eq!(record.payload.deserialize::<Vec<u32>>().unwrap(), [1, 2]);
86//! assert_eq!(deser_cbor::to_vec(&record).unwrap(), input);
87//! ```
88//!
89//! See [`Raw`](deser_core::ext::Raw) for more information.
90//!
91//! # Features
92//!
93//! * `io` (enabled by default): reading and writing streams of the
94//! standard library, see [streams](#streams). Requires `std`.
95//! * `speedups` (enabled by default): validates UTF-8 with [`simdutf8`](https://docs.rs/simdutf8).
96//! * `std` (enabled by default): uses the standard library. Without it
97//! this crate only needs `alloc` (see [`no_std`](https://docs.rs/deser/latest/deser/#no_std)).
98//!
99//! # Streams
100//!
101//! Data items are read from a [`Read`](std::io::Read) with [`from_reader`]
102//! and written to a [`Write`](std::io::Write) with [`to_writer`]. To read
103//! or write [CBOR sequences](https://www.rfc-editor.org/rfc/rfc8742) (data
104//! items that follow each other, for instance on a socket) the
105//! configurations create readers and writers of
106//! [`deser::io`](deser_core::io) ([`DeserializerConfig::reader`] and
107//! [`SerializerConfig::writer`]). The reader only buffers until an item
108//! is complete:
109//!
110//! ```rust
111//! # #[cfg(feature = "io")] {
112//! use deser_cbor::{DeserializerConfig, SerializerConfig};
113//!
114//! let mut writer = SerializerConfig::new().writer(Vec::new());
115//! writer.write(&vec![1u32, 2]).unwrap();
116//! writer.write(&"three").unwrap();
117//! let bytes = writer.into_inner();
118//!
119//! let mut reader = DeserializerConfig::new().reader(&bytes[..]);
120//! assert_eq!(reader.read::<Vec<u32>>().unwrap(), Some(vec![1, 2]));
121//! assert_eq!(reader.read::<String>().unwrap().as_deref(), Some("three"));
122//! assert_eq!(reader.read::<String>().unwrap(), None);
123//! # }
124//! ```
125//!
126//! The stream serializer ([`Serializer`]) and the stream deserializer
127//! ([`StreamDeserializer`]) do not do IO themselves (see
128//! [`deser::stream`](deser_core::stream)), they also work with other kinds
129//! of IO (for instance async runtimes with `deser-tokio`) and without the
130//! standard library.
131//!
132//! # Tags
133//!
134//! Tags are not part of the deser data model. Instead they are exchanged
135//! out of band through the [`State`](deser_core::State):
136//!
137//! * When deserializing, the tags in front of a data item are published into
138//! the state for the first event of the item (the atom or the start of the
139//! map or sequence). Types can pick them up with
140//! [`take_tag`]. Types which do not care about tags never see them, which
141//! means that unknown tags are transparent.
142//! * When serializing, [`push_tag`] registers a tag of a value in the state
143//! and the serializer writes it in front of the data item.
144//! * [`Tagged`] captures the outermost tag of a value and writes it.
145//!
146//! Both directions use the same event data. This means that values which
147//! capture event data (such as [`Recording`](deser_core::de::Recording)) keep
148//! the tags: CBOR that is deserialized into a recording and serialized again
149//! retains its tags.
150//!
151//! The simplest way to work with tags is the [`Tagged`] wrapper.
152//!
153//! The bignum tags 2 and 3 are handled by the format itself: they are
154//! converted to and from integers (and [`BigInt`](deser_core::ext::BigInt) for
155//! bignums that do not fit into 128 bits). The same applies to the tags of
156//! the well-known types: date/time strings (tag 0), decimal fractions (tag
157//! 4), UUIDs (tag 37) and full-date strings (tag 1004) are converted to and
158//! from the respective [well-known types](deser_core::ext) if their content is
159//! valid. Otherwise they are passed on as tagged values.
160#![doc(html_logo_url = "https://raw.githubusercontent.com/mitsuhiko/deser/main/artwork/logo.svg")]
161#![cfg_attr(not(any(feature = "std", test)), no_std)]
162
163extern crate alloc;
164
165mod copy;
166mod de;
167mod float;
168mod parser;
169mod raw;
170mod ser;
171mod simple;
172mod stream;
173mod tag;
174
175pub use self::de::{Deserializer, DeserializerConfig, DeserializerConfigBuilder, Iter, from_slice};
176pub use self::raw::{Cbor, RawCbor};
177#[cfg(feature = "io")]
178pub use self::ser::to_writer;
179pub use self::ser::{Serializer, SerializerConfig, SerializerConfigBuilder, to_vec};
180pub use self::simple::Simple;
181pub use self::stream::StreamDeserializer;
182#[cfg(feature = "io")]
183pub use self::stream::from_reader;
184pub use self::tag::{Tagged, push_tag, take_tag};