use std::fmt;
use std::ops::Range;
use incrementalmerkletree::{Address, Position};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ShardTreeError<S> {
Query(QueryError),
Insert(InsertionError),
Storage(S),
}
impl<S> From<QueryError> for ShardTreeError<S> {
fn from(err: QueryError) -> Self {
ShardTreeError::Query(err)
}
}
impl<S> From<InsertionError> for ShardTreeError<S> {
fn from(err: InsertionError) -> Self {
ShardTreeError::Insert(err)
}
}
impl<S: fmt::Display> fmt::Display for ShardTreeError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
ShardTreeError::Query(q) => q.fmt(f),
ShardTreeError::Insert(i) => i.fmt(f),
ShardTreeError::Storage(s) => {
write!(
f,
"An error occurred persisting or retrieving tree data: {}",
s
)
}
}
}
}
impl<SE> std::error::Error for ShardTreeError<SE>
where
SE: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match &self {
ShardTreeError::Storage(e) => Some(e),
_ => None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum InsertionError {
NotContained(Address),
OutOfRange(Position, Range<Position>),
Conflict(Address),
CheckpointOutOfOrder,
TreeFull,
InputMalformed(Address),
MarkedRetentionInvalid,
}
impl fmt::Display for InsertionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
InsertionError::NotContained(addr) => {
write!(f, "Tree does not contain a root at address {:?}", addr)
}
InsertionError::OutOfRange(p, r) => {
write!(
f,
"Attempted insertion point {:?} is not in range {:?}",
p, r
)
}
InsertionError::Conflict(addr) => write!(
f,
"Inserted root conflicts with existing root at address {:?}",
addr
),
InsertionError::CheckpointOutOfOrder => {
write!(f, "Cannot append out-of-order checkpoint identifier.")
}
InsertionError::TreeFull => write!(f, "Note commitment tree is full."),
InsertionError::InputMalformed(addr) => {
write!(f, "Input malformed for insertion at address {:?}", addr)
}
InsertionError::MarkedRetentionInvalid => {
write!(f, "Cannot use `Marked` retention for the empty tree.")
}
}
}
}
impl std::error::Error for InsertionError {}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum QueryError {
NotContained(Address),
CheckpointPruned,
TreeIncomplete(Vec<Address>),
}
impl fmt::Display for QueryError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
QueryError::NotContained(addr) => {
write!(f, "Tree does not contain a root at address {:?}", addr)
}
QueryError::CheckpointPruned => {
write!(
f,
"The leaf corresponding to the requested checkpoint is not present in the tree."
)
}
QueryError::TreeIncomplete(addrs) => {
write!(
f,
"Unable to compute root; missing values for nodes {:?}",
addrs
)
}
}
}
}
impl std::error::Error for QueryError {}