1#[cfg(doc)]
2use crate::{Hash, Resolve};
3
4#[macro_export]
5macro_rules! error_parse {
7 ($($t:tt)*) => {
8 $crate::Error::Parse($crate::anyhow!($($t)*))
9 };
10}
11
12#[macro_export]
13macro_rules! error_fetch {
15 ($($t:tt)*) => {
16 $crate::Error::Fetch($crate::anyhow!($($t)*))
17 };
18}
19
20#[macro_export]
21macro_rules! error_operation {
23 ($($t:tt)*) => {
24 $crate::Error::Operation($crate::anyhow!($($t)*))
25 };
26}
27
28#[macro_export]
29macro_rules! error_consistency {
31 ($($t:tt)*) => {
32 $crate::Error::Consistency($crate::anyhow!($($t)*))
33 };
34}
35
36#[derive(Debug, thiserror::Error)]
38#[non_exhaustive]
39pub enum Error {
40 #[error(transparent)]
42 Parse(anyhow::Error),
43 #[error(transparent)]
45 Fetch(anyhow::Error),
46 #[error(transparent)]
48 Operation(anyhow::Error),
49 #[error(transparent)]
51 Consistency(anyhow::Error),
52 #[error(transparent)]
54 Io(#[from] std::io::Error),
55 #[error("extra input left")]
57 ExtraInputLeft,
58 #[error("end of input")]
60 EndOfInput,
61 #[error("address index out of bounds")]
63 AddressOutOfBounds,
64 #[error("hash resolution mismatch")]
66 ResolutionMismatch,
67 #[error("full hash mismatch")]
69 FullHashMismatch,
70 #[error("discriminant overflow")]
72 DiscriminantOverflow,
73 #[error("zero")]
75 Zero,
76 #[error("out of bounds")]
78 OutOfBounds,
79 #[error("length out of bounds")]
81 UnsupportedLength,
82 #[error(transparent)]
84 Utf8(#[from] std::string::FromUtf8Error),
85 #[error("not implemented")]
87 Unimplemented,
88 #[error("hash not found in the resolve")]
90 HashNotFound,
91 #[error("interrupted")]
93 Interrupted,
94}
95
96impl Error {
97 pub fn parse(e: impl Into<anyhow::Error>) -> Self {
99 Self::Parse(e.into())
100 }
101
102 pub fn fetch(e: impl Into<anyhow::Error>) -> Self {
104 Self::Fetch(e.into())
105 }
106
107 pub fn operation(e: impl Into<anyhow::Error>) -> Self {
109 Self::Operation(e.into())
110 }
111
112 pub fn consistency(e: impl Into<anyhow::Error>) -> Self {
114 Self::Consistency(e.into())
115 }
116
117 pub fn io(e: impl Into<std::io::Error>) -> Self {
119 e.into().into()
120 }
121
122 fn io_kind(&self) -> std::io::ErrorKind {
123 use std::io::ErrorKind;
124 match self {
125 Error::Parse(_) => ErrorKind::InvalidData,
126 Error::Fetch(_) => ErrorKind::Other,
127 Error::Operation(_) => ErrorKind::Other,
128 Error::Consistency(_) => ErrorKind::InvalidData,
129 Error::Io(e) => e.kind(),
130 Error::ExtraInputLeft => ErrorKind::InvalidData,
131 Error::EndOfInput => ErrorKind::UnexpectedEof,
132 Error::AddressOutOfBounds => ErrorKind::Other,
133 Error::ResolutionMismatch => ErrorKind::InvalidData,
134 Error::FullHashMismatch => ErrorKind::InvalidData,
135 Error::DiscriminantOverflow => ErrorKind::InvalidData,
136 Error::Zero => ErrorKind::InvalidData,
137 Error::OutOfBounds => ErrorKind::InvalidData,
138 Error::UnsupportedLength => ErrorKind::FileTooLarge,
139 Error::Utf8(_) => ErrorKind::InvalidData,
140 Error::Unimplemented => ErrorKind::Unsupported,
141 Error::HashNotFound => ErrorKind::NotFound,
142 Error::Interrupted => ErrorKind::Interrupted,
143 }
144 }
145}
146
147impl From<Error> for std::io::Error {
148 fn from(value: Error) -> Self {
149 match value {
150 Error::Io(e) => e,
151 e => Self::new(e.io_kind(), e),
152 }
153 }
154}
155
156pub type Result<T> = std::result::Result<T, Error>;