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 [`Encode`] 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 [`EncoderStatus::Finished`].
23//!
24//! # Decoding
25//!
26//! Types implement [`Decode`] to produce a [`Decoder`], which consumes bytes via
27//! [`Decoder::push_bytes`] until it signals completion by returning `Ok(DecoderStatus::Ready)`. The
28//! caller then 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 stdlib 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//! * [`drain_to_writer`]: Drain an encoder to a stdlib writer.
48//! * [`encode_to_vec`]: Encode to the heap.
49//! * [`drain_to_vec`]: Drain 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#[doc(inline)]
81pub use self::decode::{
82 check_decode, check_decoder, decode_from_slice, decode_from_slice_unbounded, Decode, Decoder,
83 DecoderStatus,
84};
85#[cfg(feature = "std")]
86#[doc(inline)]
87pub use self::decode::{
88 decode_from_read, decode_from_read_unbuffered, decode_from_read_unbuffered_with,
89};
90#[doc(inline)]
91pub use self::encode::encoders::{
92 ArrayEncoder, ArrayRefEncoder, BytesEncoder, Encoder2, Encoder3, Encoder4, Encoder6,
93 SliceEncoder,
94};
95#[doc(inline)]
96pub use self::encode::{
97 check_encode, check_encoder, Encode, Encoder, EncoderByteIter, EncoderStatus, ExactSizeEncoder,
98};
99#[cfg(feature = "alloc")]
100#[doc(inline)]
101pub use self::encode::{drain_to_vec, encode_to_vec};
102#[cfg(feature = "std")]
103#[doc(inline)]
104pub use self::encode::{drain_to_writer, encode_to_writer};
105#[cfg(feature = "alloc")]
106#[doc(no_inline)]
107pub use self::error::LengthPrefixExceedsMaxError;
108#[cfg(feature = "std")]
109#[doc(no_inline)]
110pub use self::error::ReadError;
111#[cfg(feature = "alloc")]
112#[doc(no_inline)]
113pub use self::error::{ByteVecDecoderError, VecDecoderError};
114#[doc(no_inline)]
115pub use self::error::{
116 CompactSizeDecoderError, DecodeError, Decoder2Error, Decoder3Error, Decoder4Error,
117 Decoder6Error, UnconsumedError, UnexpectedEofError,
118};