1#[macro_export]
2macro_rules! error_parse {
4 ($($t:tt)*) => {
5 $crate::Error::Parse($crate::anyhow!($($t)*))
6 };
7}
8
9#[macro_export]
10macro_rules! error_fetch {
12 ($($t:tt)*) => {
13 $crate::Error::Fetch($crate::anyhow!($($t)*))
14 };
15}
16
17#[macro_export]
18macro_rules! error_operation {
20 ($($t:tt)*) => {
21 $crate::Error::Operation($crate::anyhow!($($t)*))
22 };
23}
24
25#[macro_export]
26macro_rules! error_consistency {
28 ($($t:tt)*) => {
29 $crate::Error::Consistency($crate::anyhow!($($t)*))
30 };
31}
32
33#[derive(Debug, thiserror::Error)]
35#[non_exhaustive]
36pub enum Error {
37 #[error(transparent)]
39 Parse(anyhow::Error),
40 #[error(transparent)]
42 Fetch(anyhow::Error),
43 #[error(transparent)]
45 Operation(anyhow::Error),
46 #[error(transparent)]
48 Consistency(anyhow::Error),
49 #[error(transparent)]
50 Io(#[from] std::io::Error),
51 #[error("extra input left")]
53 ExtraInputLeft,
54 #[error("end of input")]
56 EndOfInput,
57 #[error("address index out of bounds")]
59 AddressOutOfBounds,
60 #[error("hash resolution mismatch")]
62 ResolutionMismatch,
63 #[error("full hash mismatch")]
65 FullHashMismatch,
66 #[error("discriminant overflow")]
68 DiscriminantOverflow,
69 #[error("zero")]
71 Zero,
72 #[error("out of bounds")]
74 OutOfBounds,
75 #[error("length out of bounds")]
77 UnsupportedLength,
78 #[error(transparent)]
80 Utf8(#[from] std::string::FromUtf8Error),
81 #[error("unknown extension")]
83 UnknownExtension,
84 #[error("wrong extension type")]
86 ExtensionType,
87 #[error("not implemented")]
88 Unimplemented,
89 #[error("hash not found in the resolve")]
90 HashNotFound,
91 #[error("interrupted")]
92 Interrupted,
93}
94
95impl Error {
96 pub fn parse(e: impl Into<anyhow::Error>) -> Self {
98 Self::Parse(e.into())
99 }
100
101 pub fn fetch(e: impl Into<anyhow::Error>) -> Self {
103 Self::Fetch(e.into())
104 }
105
106 pub fn operation(e: impl Into<anyhow::Error>) -> Self {
108 Self::Fetch(e.into())
109 }
110
111 pub fn consistency(e: impl Into<anyhow::Error>) -> Self {
113 Self::Fetch(e.into())
114 }
115
116 pub fn io(e: impl Into<std::io::Error>) -> Self {
117 e.into().into()
118 }
119
120 fn io_kind(&self) -> std::io::ErrorKind {
121 use std::io::ErrorKind;
122 match self {
123 Error::Parse(_) => ErrorKind::InvalidData,
124 Error::Fetch(_) => ErrorKind::Other,
125 Error::Operation(_) => ErrorKind::Other,
126 Error::Consistency(_) => ErrorKind::InvalidData,
127 Error::Io(e) => e.kind(),
128 Error::ExtraInputLeft => ErrorKind::InvalidData,
129 Error::EndOfInput => ErrorKind::UnexpectedEof,
130 Error::AddressOutOfBounds => ErrorKind::Other,
131 Error::ResolutionMismatch => ErrorKind::InvalidData,
132 Error::FullHashMismatch => ErrorKind::InvalidData,
133 Error::DiscriminantOverflow => ErrorKind::InvalidData,
134 Error::Zero => ErrorKind::InvalidData,
135 Error::OutOfBounds => ErrorKind::InvalidData,
136 Error::UnsupportedLength => ErrorKind::FileTooLarge,
137 Error::Utf8(_) => ErrorKind::InvalidData,
138 Error::UnknownExtension => ErrorKind::Other,
139 Error::ExtensionType => ErrorKind::Other,
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>;