use core::fmt;
use eth_valkyoth_codec::{DecodeError, DecodeErrorCategory};
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WithdrawalField {
List,
Withdrawal,
Index,
ValidatorIndex,
Address,
Amount,
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WithdrawalDecodeError {
WrongFieldCount {
expected: usize,
found: usize,
},
FieldDecode {
field: WithdrawalField,
source: DecodeError,
},
InvalidAddressLength {
found: usize,
},
ZeroAmount,
}
impl WithdrawalDecodeError {
#[must_use]
pub const fn code(self) -> &'static str {
match self {
Self::WrongFieldCount { .. } => "ETH_WITHDRAWAL_WRONG_FIELD_COUNT",
Self::FieldDecode { source, .. } => source.code(),
Self::InvalidAddressLength { .. } => "ETH_WITHDRAWAL_INVALID_ADDRESS_LENGTH",
Self::ZeroAmount => "ETH_WITHDRAWAL_ZERO_AMOUNT",
}
}
#[must_use]
pub const fn message(self) -> &'static str {
match self {
Self::WrongFieldCount { .. } => "withdrawal must contain exactly four RLP fields",
Self::FieldDecode { .. } => "withdrawal field failed bounded decoding",
Self::InvalidAddressLength { .. } => "withdrawal address must be exactly 20 bytes",
Self::ZeroAmount => "withdrawal amount must be nonzero",
}
}
#[must_use]
pub const fn category(self) -> WithdrawalDecodeErrorCategory {
match self {
Self::WrongFieldCount { .. } | Self::InvalidAddressLength { .. } | Self::ZeroAmount => {
WithdrawalDecodeErrorCategory::MalformedInput
}
Self::FieldDecode { source, .. } => match source.category() {
DecodeErrorCategory::ResourceExhaustion => {
WithdrawalDecodeErrorCategory::ResourceExhaustion
}
_ => WithdrawalDecodeErrorCategory::MalformedInput,
},
}
}
}
impl fmt::Display for WithdrawalDecodeError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.message())
}
}
#[cfg(feature = "std")]
impl std::error::Error for WithdrawalDecodeError {}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WithdrawalDecodeErrorCategory {
MalformedInput,
ResourceExhaustion,
}