bitcoin_consensus_encoding/lib.rs
1// SPDX-License-Identifier: CC0-1.0
2
3//! # Rust Bitcoin Consensus Encoding
4//!
5//! Traits and utilities for encoding and decoding Bitcoin data types in a consensus-consistent way,
6//! using a *sans-I/O* architecture.
7//!
8//! Rather than reading from or writing to [`std::io::Read`]/[`std::io::Write`] traits directly, the
9//! codec types work with byte slices. This keeps codec logic I/O-agnostic, so the same
10//! implementation works in `no_std` environments, sync I/O, async I/O, and hash engines without
11//! duplicating logic or surfacing I/O errors in non-I/O contexts (e.g. when hashing an encoding).
12//!
13//! *Consensus* encoding is the canonical byte representation of Bitcoin data types used across the
14//! peer-to-peer network and transaction serialization. This crate only supports deterministic
15//! encoding and will never support types like floats whose encoding is non-deterministic or
16//! platform-dependent.
17//!
18//! # Encoding
19//!
20//! Types implement [`Encodable`] to produce an [`Encoder`], which yields encoded bytes in chunks
21//! via [`Encoder::current_chunk`] and [`Encoder::advance`]. The caller drives the process by
22//! pulling chunks until `advance` returns `false`.
23//!
24//! # Decoding
25//!
26//! Types implement [`Decodable`] to produce a [`Decoder`], which consumes bytes via
27//! [`Decoder::push_bytes`] until it signals completion by returning `Ok(false)`. The caller then
28//! calls [`Decoder::end`] to obtain the decoded value.
29//!
30//! Unlike encoding, decoding is fallible. Both `push_bytes` and `end` return `Result`. I/O errors
31//! are handled by the caller, keeping the codec logic I/O-agnostic.
32//!
33//! # Drivers
34//!
35//! This crate provides free functions which drive codecs for common I/O interfaces. On the decoding
36//! side we provide:
37//!
38//! * [`decode_from_read`]: Decode from a stblib buffered reader.
39//! * [`decode_from_read_unbuffered`]: Decode from a stdlib unbuffered reader (4k buffer on stack).
40//! * [`decode_from_read_unbuffered_with`]: As above with custom sized stack-allocated buffer.
41//! * [`decode_from_slice`]: Decode from a byte slice (errors if slice is not completely consumed).
42//! * [`decode_from_slice_unbounded`]: Slice can contain additional data after decoding completes.
43//!
44//! And on the encoding side we provide:
45//!
46//! * [`encode_to_writer`]: Encode to a stdlib writer.
47//! * [`flush_to_writer`]: Flush an encoder to a stdlib writer.
48//! * [`encode_to_vec`]: Encode to the heap.
49//! * [`flush_to_vec`]: Flush an encoder to the heap.
50//!
51//! # Feature Flags
52//!
53//! * `std` - Enables std lib I/O driver functions and `std::error::Error` impls (implies `alloc`).
54//! * `alloc` - Enables [`encode_to_vec`], `Vec`-based decoders, and allocation-based helpers.
55
56#![no_std]
57// Coding conventions.
58#![warn(missing_docs)]
59#![warn(deprecated_in_future)]
60#![doc(test(attr(warn(unused))))]
61
62#[cfg(feature = "alloc")]
63extern crate alloc;
64#[cfg(feature = "std")]
65extern crate std;
66
67mod compact_size;
68mod decode;
69mod encode;
70
71pub mod error;
72
73#[doc(inline)]
74pub use self::compact_size::{CompactSizeDecoder, CompactSizeEncoder, CompactSizeU64Decoder};
75#[doc(inline)]
76pub use self::decode::decoders::{ArrayDecoder, Decoder2, Decoder3, Decoder4, Decoder6};
77#[cfg(feature = "alloc")]
78#[doc(inline)]
79pub use self::decode::decoders::{ByteVecDecoder, VecDecoder};
80#[cfg(feature = "std")]
81#[doc(inline)]
82pub use self::decode::{
83 decode_from_read, decode_from_read_unbuffered, decode_from_read_unbuffered_with,
84};
85#[doc(inline)]
86pub use self::decode::{decode_from_slice, decode_from_slice_unbounded, Decodable, Decoder};
87#[doc(inline)]
88pub use self::encode::encoders::{
89 ArrayEncoder, ArrayRefEncoder, BytesEncoder, Encoder2, Encoder3, Encoder4, Encoder6,
90 SliceEncoder,
91};
92#[cfg(feature = "alloc")]
93#[doc(inline)]
94pub use self::encode::{encode_to_vec, flush_to_vec};
95#[cfg(feature = "std")]
96#[doc(inline)]
97pub use self::encode::{encode_to_writer, flush_to_writer};
98#[doc(inline)]
99pub use self::encode::{Encodable, EncodableByteIter, Encoder, ExactSizeEncoder};
100#[cfg(feature = "alloc")]
101#[doc(no_inline)]
102pub use self::error::LengthPrefixExceedsMaxError;
103#[cfg(feature = "std")]
104#[doc(no_inline)]
105pub use self::error::ReadError;
106#[cfg(feature = "alloc")]
107#[doc(no_inline)]
108pub use self::error::{ByteVecDecoderError, VecDecoderError};
109#[doc(no_inline)]
110pub use self::error::{
111 CompactSizeDecoderError, DecodeError, Decoder2Error, Decoder3Error, Decoder4Error,
112 Decoder6Error, UnconsumedError, UnexpectedEofError,
113};