1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Principled encoding and decoding of values.
//!
//! ```
//! use ufotofu::codec_prelude::*;
//! use ufotofu::codec::endian::U32BE;
//!
//! # pollster::block_on(async{
//! let mut buf = [99; 5];
//! let mut con = (&mut buf).into_consumer();
//!
//! // Encode a u32 into big-endian bytes...
//! U32BE(258).encode(&mut con).await.unwrap();
//!
//! assert_eq!(buf, [0, 0, 1, 2, 99]);
//!
//! // ...and decode them back into a u32.
//! let mut pro = buf.into_producer();
//! assert_eq!(U32BE::decode_canonic(&mut pro).await.unwrap().0, 258);
//! # });
//! ```
//!
//! This module provides traits for types which can be encoded and decoded into sequences of symbols of some other type (typically, `u8`s). Not every mapping from a type to sequences of symbols constitutes a useful definition of an encoding, however. Intuitively speaking, our traits require the following properties:
//!
//! - each value has at least one encoding (ensuring everything can be encoded),
//! - no two distinct values have the same encoding (ensuring decoding works as expected), and
//! - no encoding is a prefix of another encoding (ensuring you can sequentially decode concatenations of arbitrary encodings).
//!
//! To make these requirements more formally precise, let `T` be a type for which we wish to define an encoding into symbols of type `S`. We say a set of pairs of type `(T, &[S])` (i.e., a [binary relation](https://en.wikipedia.org/wiki/Binary_relation) on `T` and `&[S]`) is an *encoding relation* if
//!
//! - for all `t` of type `T`, there is at least one pair `(t, _)` in the relation (i.e., the relation is a [total function](https://en.wikipedia.org/wiki/Function_(mathematics))),
//! - for all `t1` and `t2` of type `T` and all `enc` of type `&[S]`, if both `(t1, enc)` and `(t2, enc)` are in the relation, then `t1 == t2` (i.e., the relation is [injective](https://en.wikipedia.org/wiki/Injective_function)), and
//! - for all `t1` and `t2` of type `T` and all `enc1` and `enc2` of type `&[S]`, if `(t1, enc1)` and `(t2, enc2)` are in the relation, then `enc1` is not a strict prefix of `enc2` (i.e., the relation is a [prefix code](https://en.wikipedia.org/wiki/Prefix_code)).
//!
//! ## Traits
//!
//! The [`Encodable`] and [`Decodable`] traits describe types with proper encoding relations, with [`Encodable::encode`] specifying how to encode a value into a [`BulkConsumer`](crate::BulkConsumer) of code symbols, and [`Decodable::decode`] specifying how to decode a value from a [`BulkProducer`](crate::BulkProducer) of code symbols.
//!
//! The [`EncodableKnownLength`] trait specialises [`Encodable`] for types which can precompute the number of symbols in their encoding. And the [`DecodableCanonic`] trait specialises [`Decodable`] for types in which there is a one-to-one mapping between values and codes.
//!
//! ## Encoders and Decoders
//!
//! The [`adaptors`] module provide adaptors that turn bulk consumers of code symbols into consumers of encodables, and bulk producers of code symbols into producers of decodables.
//!
//! ## Property Testing
//!
//! When the `dev` feature is enabled, the [`proptest`] module provides helpers for writing property tests for checking the invariants that implementations of the codec traits must uphold.
//!
//! ---
//!
//! See also the [`codec_relative`](crate::codec_relative) module for working with encodings relative to some context shared between encoder and decoder.
pub use *;
pub use *;
pub use ;