use alloc::string::String;
use core::fmt::{self, Display, Formatter};
#[cfg(feature = "std")]
use std::error::Error as StdError;
use super::{ChunkWithProof, Digest};
use crate::bytesrepr;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
IncorrectDigestLength(usize),
Base16DecodeError(base16::DecodeError),
}
impl Display for Error {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match self {
Error::IncorrectDigestLength(length) => {
write!(
formatter,
"incorrect digest length {}, expected length {}.",
length,
Digest::LENGTH
)
}
Error::Base16DecodeError(error) => {
write!(formatter, "base16 decode error: {}", error)
}
}
}
}
#[cfg(feature = "std")]
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Error::IncorrectDigestLength(_) => None,
Error::Base16DecodeError(error) => Some(error),
}
}
}
#[derive(Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum MerkleVerificationError {
IndexOutOfBounds {
count: u64,
index: u64,
},
UnexpectedProofLength {
count: u64,
index: u64,
expected_proof_length: u8,
actual_proof_length: usize,
},
}
impl Display for MerkleVerificationError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match self {
MerkleVerificationError::IndexOutOfBounds { count, index } => {
write!(
formatter,
"index out of bounds - count: {}, index: {}",
count, index
)
}
MerkleVerificationError::UnexpectedProofLength {
count,
index,
expected_proof_length,
actual_proof_length,
} => {
write!(
formatter,
"unexpected proof length - count: {}, index: {}, expected length: {}, actual \
length: {}",
count, index, expected_proof_length, actual_proof_length
)
}
}
}
}
#[cfg(feature = "std")]
impl StdError for MerkleVerificationError {}
#[derive(Debug)]
#[non_exhaustive]
pub enum ChunkWithProofVerificationError {
MerkleVerificationError(MerkleVerificationError),
ChunkWithProofHasEmptyMerkleProof {
chunk_with_proof: ChunkWithProof,
},
UnexpectedRootHash,
Bytesrepr(bytesrepr::Error),
FirstDigestInMerkleProofDidNotMatchHashOfChunk {
first_digest_in_indexed_merkle_proof: Digest,
hash_of_chunk: Digest,
},
}
impl Display for ChunkWithProofVerificationError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match self {
ChunkWithProofVerificationError::MerkleVerificationError(error) => {
write!(formatter, "{}", error)
}
ChunkWithProofVerificationError::ChunkWithProofHasEmptyMerkleProof {
chunk_with_proof,
} => {
write!(
formatter,
"chunk with proof has empty merkle proof: {:?}",
chunk_with_proof
)
}
ChunkWithProofVerificationError::UnexpectedRootHash => {
write!(formatter, "merkle proof has an unexpected root hash")
}
ChunkWithProofVerificationError::Bytesrepr(error) => {
write!(
formatter,
"bytesrepr error computing chunkable hash: {}",
error
)
}
ChunkWithProofVerificationError::FirstDigestInMerkleProofDidNotMatchHashOfChunk {
first_digest_in_indexed_merkle_proof,
hash_of_chunk,
} => {
write!(
formatter,
"first digest in merkle proof did not match hash of chunk - first digest: \
{:?}, hash of chunk: {:?}",
first_digest_in_indexed_merkle_proof, hash_of_chunk
)
}
}
}
}
impl From<MerkleVerificationError> for ChunkWithProofVerificationError {
fn from(error: MerkleVerificationError) -> Self {
ChunkWithProofVerificationError::MerkleVerificationError(error)
}
}
#[cfg(feature = "std")]
impl StdError for ChunkWithProofVerificationError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
ChunkWithProofVerificationError::MerkleVerificationError(error) => Some(error),
ChunkWithProofVerificationError::Bytesrepr(error) => Some(error),
ChunkWithProofVerificationError::ChunkWithProofHasEmptyMerkleProof { .. }
| ChunkWithProofVerificationError::UnexpectedRootHash
| ChunkWithProofVerificationError::FirstDigestInMerkleProofDidNotMatchHashOfChunk {
..
} => None,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
#[non_exhaustive]
pub enum MerkleConstructionError {
IndexOutOfBounds {
count: u64,
index: u64,
},
TooManyLeaves {
count: String,
},
}
impl Display for MerkleConstructionError {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
match self {
MerkleConstructionError::IndexOutOfBounds { count, index } => {
write!(
formatter,
"could not construct merkle proof - index out of bounds - count: {}, index: {}",
count, index
)
}
MerkleConstructionError::TooManyLeaves { count } => {
write!(
formatter,
"could not construct merkle proof - too many leaves - count: {}, max: {} \
(u64::MAX)",
count,
u64::MAX
)
}
}
}
}
#[cfg(feature = "std")]
impl StdError for MerkleConstructionError {}