consensus_encoding: Move errors to submodule
What changed, and why it matters
This commit is a pure code reorganization: it moves existing error type definitions from several source files into a new dedicated `error` submodule and re-exports them at the crate root. There are no functional changes to how data is encoded or decoded, no bug fixes, and no security-relevant behavior changes.
No security action required; this is a routine refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors consensus_encoding by creating consensus_encoding/src/error.rs and relocating error structs/enums (CompactSizeDecoderError, LengthPrefixExceedsMaxError, ByteVecDecoderError, VecDecoderError, UnexpectedEofError, DecoderNError, ReadError, DecodeError, UnconsumedError) from compact_size.rs, decode/decoders.rs, and decode/mod.rs. Visibility is adjusted: inner enums and some fields become pub(crate) instead of private, but the public API is preserved via re-exports in lib.rs with #[doc(inline)]/#[doc(no_inline)] attributes for documentation clarity. No logic, bounds checks, or parsing behavior is altered.
Changed components
consensus_encoding/src/compact_size.rsconsensus_encoding/src/decode/decoders.rsconsensus_encoding/src/decode/mod.rsconsensus_encoding/src/error.rsconsensus_encoding/src/lib.rsInspect captured patch +450 / −417
diff --git a/consensus_encoding/src/compact_size.rs b/consensus_encoding/src/compact_size.rs
index 824720b7..77806065 100644
--- a/consensus_encoding/src/compact_size.rs
+++ b/consensus_encoding/src/compact_size.rs
@@ -6,12 +6,13 @@
//! consensus protocol to usually to encode collection lengths. However, there are
//! also some unique non-length use cases.
-use core::convert::Infallible;
-
use internals::array_vec::ArrayVec;
use crate::decode::Decoder;
use crate::encode::{Encoder, ExactSizeEncoder};
+use crate::error::{
+ CompactSizeDecoderError, CompactSizeDecoderErrorInner, LengthPrefixExceedsMaxError,
+};
/// Maximum size, in bytes, of a vector we are allowed to decode.
///
@@ -321,89 +322,6 @@ fn compact_size_decode_u64(buf: &ArrayVec<u8, 9>) -> Result<u64, CompactSizeDeco
}
}
-/// An error consensus decoding a compact size encoded integer.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct CompactSizeDecoderError(CompactSizeDecoderErrorInner);
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-enum CompactSizeDecoderErrorInner {
- /// Returned when the decoder reaches end of stream (EOF).
- UnexpectedEof {
- /// How many bytes were required.
- required: usize,
- /// How many bytes were received.
- received: usize,
- },
- /// Returned when the encoding is not minimal
- NonMinimal {
- /// The encoded value.
- value: u64,
- },
- /// Returned when the encoded value exceeds the decoder's limit.
- ValueExceedsLimit(LengthPrefixExceedsMaxError),
-}
-
-impl From<Infallible> for CompactSizeDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl core::fmt::Display for CompactSizeDecoderError {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- use internals::write_err;
- use CompactSizeDecoderErrorInner as E;
-
- match self.0 {
- E::UnexpectedEof { required: 1, received: 0 } => {
- write!(f, "required at least one byte but the input is empty")
- }
- E::UnexpectedEof { required, received: 0 } => {
- write!(f, "required at least {} bytes but the input is empty", required)
- }
- E::UnexpectedEof { required, received } => write!(
- f,
- "required at least {} bytes but only {} bytes were received",
- required, received
- ),
- E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
- E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for CompactSizeDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- use CompactSizeDecoderErrorInner as E;
-
- match self {
- Self(E::ValueExceedsLimit(ref e)) => Some(e),
- _ => None,
- }
- }
-}
-
-/// The error returned when a compact size value exceeds a configured limit.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct LengthPrefixExceedsMaxError {
- /// The limit that was exceeded.
- limit: usize,
- /// The value that exceeded the limit.
- value: u64,
-}
-
-impl From<Infallible> for LengthPrefixExceedsMaxError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl core::fmt::Display for LengthPrefixExceedsMaxError {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for LengthPrefixExceedsMaxError {}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/consensus_encoding/src/decode/decoders.rs b/consensus_encoding/src/decode/decoders.rs
index cb182387..7716660a 100644
--- a/consensus_encoding/src/decode/decoders.rs
+++ b/consensus_encoding/src/decode/decoders.rs
@@ -4,16 +4,18 @@
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
-use core::convert::Infallible;
use core::{fmt, mem};
-use internals::write_err;
-
#[cfg(feature = "alloc")]
use super::Decodable;
use super::Decoder;
#[cfg(feature = "alloc")]
-use crate::compact_size::{CompactSizeDecoder, CompactSizeDecoderError};
+use crate::compact_size::CompactSizeDecoder;
+#[cfg(feature = "alloc")]
+use crate::error::{
+ ByteVecDecoderError, ByteVecDecoderErrorInner, VecDecoderError, VecDecoderErrorInner,
+};
+use crate::{Decoder2Error, Decoder3Error, Decoder4Error, Decoder6Error, UnexpectedEofError};
/// Maximum amount of memory (in bytes) to allocate at once when deserializing vectors.
#[cfg(feature = "alloc")]
@@ -681,216 +683,6 @@ where
fn read_limit(&self) -> usize { self.inner.read_limit() }
}
-/// The error returned by the [`ByteVecDecoder`].
-#[cfg(feature = "alloc")]
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ByteVecDecoderError(ByteVecDecoderErrorInner);
-
-#[cfg(feature = "alloc")]
-#[derive(Debug, Clone, PartialEq, Eq)]
-enum ByteVecDecoderErrorInner {
- /// Error decoding the byte vector length prefix.
- LengthPrefixDecode(CompactSizeDecoderError),
- /// Not enough bytes given to decoder.
- UnexpectedEof(UnexpectedEofError),
-}
-
-#[cfg(feature = "alloc")]
-impl From<Infallible> for ByteVecDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-#[cfg(feature = "alloc")]
-impl fmt::Display for ByteVecDecoderError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use ByteVecDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
- E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
- }
- }
-}
-
-#[cfg(all(feature = "std", feature = "alloc"))]
-impl std::error::Error for ByteVecDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- use ByteVecDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => Some(e),
- E::UnexpectedEof(ref e) => Some(e),
- }
- }
-}
-
-/// The error returned by the [`VecDecoder`].
-#[cfg(feature = "alloc")]
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct VecDecoderError<Err>(VecDecoderErrorInner<Err>);
-
-#[cfg(feature = "alloc")]
-#[derive(Debug, Clone, PartialEq, Eq)]
-enum VecDecoderErrorInner<Err> {
- /// Error decoding the vector length prefix.
- LengthPrefixDecode(CompactSizeDecoderError),
- /// Error while decoding an item.
- Item(Err),
- /// Not enough bytes given to decoder.
- UnexpectedEof(UnexpectedEofError),
-}
-
-#[cfg(feature = "alloc")]
-impl<Err> From<Infallible> for VecDecoderError<Err> {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-#[cfg(feature = "alloc")]
-impl<Err> fmt::Display for VecDecoderError<Err>
-where
- Err: fmt::Display + fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use VecDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
- E::Item(ref e) => write_err!(f, "vec decoder error"; e),
- E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl<Err> std::error::Error for VecDecoderError<Err>
-where
- Err: std::error::Error + 'static,
-{
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- use VecDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => Some(e),
- E::Item(ref e) => Some(e),
- E::UnexpectedEof(ref e) => Some(e),
- }
- }
-}
-
-/// Not enough bytes given to decoder.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct UnexpectedEofError {
- /// Number of bytes missing to complete decoder.
- missing: usize,
-}
-
-impl From<Infallible> for UnexpectedEofError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for UnexpectedEofError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for UnexpectedEofError {}
-
-/// Helper macro to define an error type for a `DecoderN`.
-macro_rules! define_decoder_n_error {
- (
- $(#[$attr:meta])*
- $name:ident;
- $(
- $(#[$err_attr:meta])*
- ($err_wrap:ident, $err_type:ident, $err_msg:literal),
- )*
- ) => {
- $(#[$attr])*
- #[derive(Debug, Clone, PartialEq, Eq)]
- pub enum $name<$($err_type,)*> {
- $(
- $(#[$err_attr])*
- $err_wrap($err_type),
- )*
- }
-
- impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
- where
- $($err_type: fmt::Display,)*
- {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
- }
- }
- }
-
- #[cfg(feature = "std")]
- impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
- where
- $($err_type: std::error::Error + 'static,)*
- {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- $(Self::$err_wrap(ref e) => Some(e),)*
- }
- }
- }
- };
-}
-
-define_decoder_n_error! {
- /// Error type for [`Decoder2`].
- Decoder2Error;
- /// Error from the first decoder.
- (First, A, "first decoder error."),
- /// Error from the second decoder.
- (Second, B, "second decoder error."),
-}
-
-define_decoder_n_error! {
- /// Error type for [`Decoder3`].
- Decoder3Error;
- /// Error from the first decoder.
- (First, A, "first decoder error."),
- /// Error from the second decoder.
- (Second, B, "second decoder error."),
- /// Error from the third decoder.
- (Third, C, "third decoder error."),
-}
-
-define_decoder_n_error! {
- /// Error type for [`Decoder4`].
- Decoder4Error;
- /// Error from the first decoder.
- (First, A, "first decoder error."),
- /// Error from the second decoder.
- (Second, B, "second decoder error."),
- /// Error from the third decoder.
- (Third, C, "third decoder error."),
- /// Error from the fourth decoder.
- (Fourth, D, "fourth decoder error."),
-}
-
-define_decoder_n_error! {
- /// Error type for [`Decoder6`].
- Decoder6Error;
- /// Error from the first decoder.
- (First, A, "first decoder error."),
- /// Error from the second decoder.
- (Second, B, "second decoder error."),
- /// Error from the third decoder.
- (Third, C, "third decoder error."),
- /// Error from the fourth decoder.
- (Fourth, D, "fourth decoder error."),
- /// Error from the fifth decoder.
- (Fifth, E, "fifth decoder error."),
- /// Error from the sixth decoder.
- (Sixth, F, "sixth decoder error."),
-}
-
#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
diff --git a/consensus_encoding/src/decode/mod.rs b/consensus_encoding/src/decode/mod.rs
index b9d1a552..8b0a52a0 100644
--- a/consensus_encoding/src/decode/mod.rs
+++ b/consensus_encoding/src/decode/mod.rs
@@ -2,13 +2,12 @@
//! Consensus Decoding Traits
-use core::convert::Infallible;
-use core::fmt;
-
-use internals::write_err;
-
pub mod decoders;
+#[cfg(feature = "std")]
+use crate::ReadError;
+use crate::{DecodeError, UnconsumedError};
+
/// A Bitcoin object which can be consensus-decoded using a push decoder.
///
/// To decode something, create a [`Self::Decoder`] and push byte slices into it with
@@ -272,100 +271,3 @@ where
decoder.end().map_err(ReadError::Decode)
}
-
-/// An error that can occur when reading and decoding from a buffered reader.
-#[cfg(feature = "std")]
-#[derive(Debug)]
-pub enum ReadError<D> {
- /// An I/O error occurred while reading from the reader.
- Io(std::io::Error),
- /// The decoder encountered an error while parsing the data.
- Decode(D),
-}
-
-#[cfg(feature = "std")]
-impl<D: core::fmt::Display> core::fmt::Display for ReadError<D> {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- match self {
- Self::Io(e) => write!(f, "I/O error: {}", e),
- Self::Decode(e) => write!(f, "decode error: {}", e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl<D> std::error::Error for ReadError<D>
-where
- D: std::error::Error + 'static,
-{
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- Self::Io(e) => Some(e),
- Self::Decode(e) => Some(e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl<D> From<std::io::Error> for ReadError<D> {
- fn from(e: std::io::Error) -> Self { Self::Io(e) }
-}
-
-/// An error that can occur when decoding from a byte slice.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub enum DecodeError<Err> {
- /// Provided slice failed to correctly decode as a type.
- Parse(Err),
- /// Bytes remained unconsumed after completing decoding.
- Unconsumed(UnconsumedError),
-}
-
-impl<Err> From<Infallible> for DecodeError<Err> {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl<Err> fmt::Display for DecodeError<Err>
-where
- Err: fmt::Display,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Self::Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
- Self::Unconsumed(ref e) => write_err!(f, "unconsumed"; e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl<Err> std::error::Error for DecodeError<Err>
-where
- Err: std::error::Error + 'static,
-{
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- Self::Parse(ref e) => Some(e),
- Self::Unconsumed(ref e) => Some(e),
- }
- }
-}
-
-/// Bytes remained unconsumed after completing decoding.
-// This is just to give us the ability to add details in a
-// non-breaking way if we want to at some stage.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct UnconsumedError();
-
-impl From<Infallible> for UnconsumedError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for UnconsumedError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "data not consumed entirely when decoding")
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for UnconsumedError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
-}
diff --git a/consensus_encoding/src/error.rs b/consensus_encoding/src/error.rs
new file mode 100644
index 00000000..3c395b3e
--- /dev/null
+++ b/consensus_encoding/src/error.rs
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! Error types for the whole crate.
+//!
+//! All error types are publicly available at the crate root.
+// We separate them into a module so the HTML docs are less cluttered.
+
+use core::convert::Infallible;
+use core::fmt;
+
+use internals::write_err;
+
+#[cfg(doc)]
+use crate::{ArrayDecoder, Decoder2, Decoder3, Decoder4, Decoder6};
+#[cfg(feature = "alloc")]
+#[cfg(doc)]
+use crate::{ByteVecDecoder, VecDecoder};
+
+/// An error that can occur when reading and decoding from a buffered reader.
+#[cfg(feature = "std")]
+#[derive(Debug)]
+pub enum ReadError<D> {
+ /// An I/O error occurred while reading from the reader.
+ Io(std::io::Error),
+ /// The decoder encountered an error while parsing the data.
+ Decode(D),
+}
+
+#[cfg(feature = "std")]
+impl<D: core::fmt::Display> core::fmt::Display for ReadError<D> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ match self {
+ Self::Io(e) => write!(f, "I/O error: {}", e),
+ Self::Decode(e) => write!(f, "decode error: {}", e),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<D> std::error::Error for ReadError<D>
+where
+ D: std::error::Error + 'static,
+{
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::Io(e) => Some(e),
+ Self::Decode(e) => Some(e),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<D> From<std::io::Error> for ReadError<D> {
+ fn from(e: std::io::Error) -> Self { Self::Io(e) }
+}
+
+/// An error that can occur when decoding from a byte slice.
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum DecodeError<Err> {
+ /// Provided slice failed to correctly decode as a type.
+ Parse(Err),
+ /// Bytes remained unconsumed after completing decoding.
+ Unconsumed(UnconsumedError),
+}
+
+impl<Err> From<Infallible> for DecodeError<Err> {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl<Err> fmt::Display for DecodeError<Err>
+where
+ Err: fmt::Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Self::Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
+ Self::Unconsumed(ref e) => write_err!(f, "unconsumed"; e),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<Err> std::error::Error for DecodeError<Err>
+where
+ Err: std::error::Error + 'static,
+{
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::Parse(ref e) => Some(e),
+ Self::Unconsumed(ref e) => Some(e),
+ }
+ }
+}
+
+/// Bytes remained unconsumed after completing decoding.
+// This is just to give us the ability to add details in a
+// non-breaking way if we want to at some stage.
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct UnconsumedError();
+
+impl From<Infallible> for UnconsumedError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for UnconsumedError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "data not consumed entirely when decoding")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for UnconsumedError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
+
+/// An error consensus decoding a compact size encoded integer.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(crate) enum CompactSizeDecoderErrorInner {
+ /// Returned when the decoder reaches end of stream (EOF).
+ UnexpectedEof {
+ /// How many bytes were required.
+ required: usize,
+ /// How many bytes were received.
+ received: usize,
+ },
+ /// Returned when the encoding is not minimal
+ NonMinimal {
+ /// The encoded value.
+ value: u64,
+ },
+ /// Returned when the encoded value exceeds the decoder's limit.
+ ValueExceedsLimit(LengthPrefixExceedsMaxError),
+}
+
+impl From<Infallible> for CompactSizeDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl core::fmt::Display for CompactSizeDecoderError {
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ use internals::write_err;
+ use CompactSizeDecoderErrorInner as E;
+
+ match self.0 {
+ E::UnexpectedEof { required: 1, received: 0 } => {
+ write!(f, "required at least one byte but the input is empty")
+ }
+ E::UnexpectedEof { required, received: 0 } => {
+ write!(f, "required at least {} bytes but the input is empty", required)
+ }
+ E::UnexpectedEof { required, received } => write!(
+ f,
+ "required at least {} bytes but only {} bytes were received",
+ required, received
+ ),
+ E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
+ E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for CompactSizeDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ use CompactSizeDecoderErrorInner as E;
+
+ match self {
+ Self(E::ValueExceedsLimit(ref e)) => Some(e),
+ _ => None,
+ }
+ }
+}
+
+/// The error returned when a compact size value exceeds a configured limit.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct LengthPrefixExceedsMaxError {
+ /// The limit that was exceeded.
+ pub(crate) limit: usize,
+ /// The value that exceeded the limit.
+ pub(crate) value: u64,
+}
+
+impl From<Infallible> for LengthPrefixExceedsMaxError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl core::fmt::Display for LengthPrefixExceedsMaxError {
+ fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+ write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for LengthPrefixExceedsMaxError {}
+
+/// The error returned by the [`ByteVecDecoder`].
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
+
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(crate) enum ByteVecDecoderErrorInner {
+ /// Error decoding the byte vector length prefix.
+ LengthPrefixDecode(CompactSizeDecoderError),
+ /// Not enough bytes given to decoder.
+ UnexpectedEof(UnexpectedEofError),
+}
+
+#[cfg(feature = "alloc")]
+impl From<Infallible> for ByteVecDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+#[cfg(feature = "alloc")]
+impl fmt::Display for ByteVecDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use ByteVecDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
+ E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
+ }
+ }
+}
+
+#[cfg(all(feature = "std", feature = "alloc"))]
+impl std::error::Error for ByteVecDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ use ByteVecDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => Some(e),
+ E::UnexpectedEof(ref e) => Some(e),
+ }
+ }
+}
+
+/// The error returned by the [`VecDecoder`].
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
+
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(crate) enum VecDecoderErrorInner<Err> {
+ /// Error decoding the vector length prefix.
+ LengthPrefixDecode(CompactSizeDecoderError),
+ /// Error while decoding an item.
+ Item(Err),
+ /// Not enough bytes given to decoder.
+ UnexpectedEof(UnexpectedEofError),
+}
+
+#[cfg(feature = "alloc")]
+impl<Err> From<Infallible> for VecDecoderError<Err> {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+#[cfg(feature = "alloc")]
+impl<Err> fmt::Display for VecDecoderError<Err>
+where
+ Err: fmt::Display + fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use VecDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
+ E::Item(ref e) => write_err!(f, "vec decoder error"; e),
+ E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<Err> std::error::Error for VecDecoderError<Err>
+where
+ Err: std::error::Error + 'static,
+{
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ use VecDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => Some(e),
+ E::Item(ref e) => Some(e),
+ E::UnexpectedEof(ref e) => Some(e),
+ }
+ }
+}
+
+/// Not enough bytes given to decoder.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct UnexpectedEofError {
+ /// Number of bytes missing to complete decoder.
+ pub(crate) missing: usize,
+}
+
+impl From<Infallible> for UnexpectedEofError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for UnexpectedEofError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for UnexpectedEofError {}
+
+/// Helper macro to define an error type for a `DecoderN`.
+macro_rules! define_decoder_n_error {
+ (
+ $(#[$attr:meta])*
+ $name:ident;
+ $(
+ $(#[$err_attr:meta])*
+ ($err_wrap:ident, $err_type:ident, $err_msg:literal),
+ )*
+ ) => {
+ $(#[$attr])*
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub enum $name<$($err_type,)*> {
+ $(
+ $(#[$err_attr])*
+ $err_wrap($err_type),
+ )*
+ }
+
+ impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
+ where
+ $($err_type: fmt::Display,)*
+ {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
+ }
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
+ where
+ $($err_type: std::error::Error + 'static,)*
+ {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ $(Self::$err_wrap(ref e) => Some(e),)*
+ }
+ }
+ }
+ };
+}
+
+define_decoder_n_error! {
+ /// Error type for [`Decoder2`].
+ Decoder2Error;
+ /// Error from the first decoder.
+ (First, A, "first decoder error."),
+ /// Error from the second decoder.
+ (Second, B, "second decoder error."),
+}
+
+define_decoder_n_error! {
+ /// Error type for [`Decoder3`].
+ Decoder3Error;
+ /// Error from the first decoder.
+ (First, A, "first decoder error."),
+ /// Error from the second decoder.
+ (Second, B, "second decoder error."),
+ /// Error from the third decoder.
+ (Third, C, "third decoder error."),
+}
+
+define_decoder_n_error! {
+ /// Error type for [`Decoder4`].
+ Decoder4Error;
+ /// Error from the first decoder.
+ (First, A, "first decoder error."),
+ /// Error from the second decoder.
+ (Second, B, "second decoder error."),
+ /// Error from the third decoder.
+ (Third, C, "third decoder error."),
+ /// Error from the fourth decoder.
+ (Fourth, D, "fourth decoder error."),
+}
+
+define_decoder_n_error! {
+ /// Error type for [`Decoder6`].
+ Decoder6Error;
+ /// Error from the first decoder.
+ (First, A, "first decoder error."),
+ /// Error from the second decoder.
+ (Second, B, "second decoder error."),
+ /// Error from the third decoder.
+ (Third, C, "third decoder error."),
+ /// Error from the fourth decoder.
+ (Fourth, D, "fourth decoder error."),
+ /// Error from the fifth decoder.
+ (Fifth, E, "fifth decoder error."),
+ /// Error from the sixth decoder.
+ (Sixth, F, "sixth decoder error."),
+}
diff --git a/consensus_encoding/src/lib.rs b/consensus_encoding/src/lib.rs
index ac9d5032..bcfecbf6 100644
--- a/consensus_encoding/src/lib.rs
+++ b/consensus_encoding/src/lib.rs
@@ -68,32 +68,46 @@ mod compact_size;
mod decode;
mod encode;
+pub mod error;
+
+#[doc(inline)]
+pub use self::compact_size::{CompactSizeDecoder, CompactSizeEncoder, CompactSizeU64Decoder};
+#[doc(inline)]
+pub use self::decode::decoders::{ArrayDecoder, Decoder2, Decoder3, Decoder4, Decoder6};
#[cfg(feature = "alloc")]
-pub use self::compact_size::LengthPrefixExceedsMaxError;
-pub use self::compact_size::{
- CompactSizeDecoder, CompactSizeDecoderError, CompactSizeEncoder, CompactSizeU64Decoder,
-};
-pub use self::decode::decoders::{
- ArrayDecoder, Decoder2, Decoder2Error, Decoder3, Decoder3Error, Decoder4, Decoder4Error,
- Decoder6, Decoder6Error, UnexpectedEofError,
-};
-#[cfg(feature = "alloc")]
-pub use self::decode::decoders::{
- ByteVecDecoder, ByteVecDecoderError, VecDecoder, VecDecoderError,
-};
+#[doc(inline)]
+pub use self::decode::decoders::{ByteVecDecoder, VecDecoder};
#[cfg(feature = "std")]
+#[doc(inline)]
pub use self::decode::{
- decode_from_read, decode_from_read_unbuffered, decode_from_read_unbuffered_with, ReadError,
-};
-pub use self::decode::{
- decode_from_slice, decode_from_slice_unbounded, Decodable, DecodeError, Decoder,
+ decode_from_read, decode_from_read_unbuffered, decode_from_read_unbuffered_with,
};
+#[doc(inline)]
+pub use self::decode::{decode_from_slice, decode_from_slice_unbounded, Decodable, Decoder};
+#[doc(inline)]
pub use self::encode::encoders::{
ArrayEncoder, ArrayRefEncoder, BytesEncoder, Encoder2, Encoder3, Encoder4, Encoder6,
SliceEncoder,
};
#[cfg(feature = "alloc")]
+#[doc(inline)]
pub use self::encode::{encode_to_vec, flush_to_vec};
#[cfg(feature = "std")]
+#[doc(inline)]
pub use self::encode::{encode_to_writer, flush_to_writer};
+#[doc(inline)]
pub use self::encode::{Encodable, EncodableByteIter, Encoder, ExactSizeEncoder};
+#[cfg(feature = "alloc")]
+#[doc(no_inline)]
+pub use self::error::LengthPrefixExceedsMaxError;
+#[cfg(feature = "std")]
+#[doc(no_inline)]
+pub use self::error::ReadError;
+#[cfg(feature = "alloc")]
+#[doc(no_inline)]
+pub use self::error::{ByteVecDecoderError, VecDecoderError};
+#[doc(no_inline)]
+pub use self::error::{
+ CompactSizeDecoderError, DecodeError, Decoder2Error, Decoder3Error, Decoder4Error,
+ Decoder6Error, UnconsumedError, UnexpectedEofError,
+};
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.