use core::fmt;
use eth_valkyoth_codec::{DecodeError, DecodeErrorCategory};
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BlockHeaderField {
ParentHash,
OmmersHash,
Beneficiary,
StateRoot,
TransactionsRoot,
ReceiptsRoot,
LogsBloom,
Difficulty,
Number,
GasLimit,
GasUsed,
Timestamp,
ExtraData,
MixHash,
Nonce,
BaseFeePerGas,
WithdrawalsRoot,
BlobGasUsed,
ExcessBlobGas,
ParentBeaconBlockRoot,
RequestsHash,
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BlockHeaderDecodeError {
Decode(DecodeError),
WrongFieldCount {
expected: usize,
found: usize,
},
FieldDecode {
field: BlockHeaderField,
source: DecodeError,
},
InvalidFieldLength {
field: BlockHeaderField,
expected: usize,
found: usize,
},
}
impl BlockHeaderDecodeError {
#[must_use]
pub const fn code(self) -> &'static str {
match self {
Self::Decode(error) => error.code(),
Self::WrongFieldCount { .. } => "ETH_HEADER_WRONG_FIELD_COUNT",
Self::FieldDecode { source, .. } => source.code(),
Self::InvalidFieldLength { .. } => "ETH_HEADER_INVALID_FIELD_LENGTH",
}
}
#[must_use]
pub const fn message(self) -> &'static str {
match self {
Self::Decode(error) => error.message(),
Self::WrongFieldCount { .. } => {
"block header field count does not match the selected field set"
}
Self::FieldDecode { .. } => "block header field failed bounded decoding",
Self::InvalidFieldLength { .. } => {
"block header fixed-width field has an invalid byte length"
}
}
}
#[must_use]
pub const fn category(self) -> BlockHeaderDecodeErrorCategory {
match self {
Self::WrongFieldCount { .. } | Self::InvalidFieldLength { .. } => {
BlockHeaderDecodeErrorCategory::MalformedInput
}
Self::Decode(error) | Self::FieldDecode { source: error, .. } => {
match error.category() {
DecodeErrorCategory::ResourceExhaustion => {
BlockHeaderDecodeErrorCategory::ResourceExhaustion
}
_ => BlockHeaderDecodeErrorCategory::MalformedInput,
}
}
}
}
}
impl fmt::Display for BlockHeaderDecodeError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.message())
}
}
#[cfg(feature = "std")]
impl std::error::Error for BlockHeaderDecodeError {}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BlockHeaderDecodeErrorCategory {
MalformedInput,
ResourceExhaustion,
}