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("unknown extension")]
87 UnknownExtension,
88 #[error("wrong extension type")]
90 ExtensionType,
91 #[error("not implemented")]
93 Unimplemented,
94 #[error("hash not found in the resolve")]
96 HashNotFound,
97 #[error("interrupted")]
99 Interrupted,
100}
101
102impl Error {
103 pub fn parse(e: impl Into<anyhow::Error>) -> Self {
105 Self::Parse(e.into())
106 }
107
108 pub fn fetch(e: impl Into<anyhow::Error>) -> Self {
110 Self::Fetch(e.into())
111 }
112
113 pub fn operation(e: impl Into<anyhow::Error>) -> Self {
115 Self::Fetch(e.into())
116 }
117
118 pub fn consistency(e: impl Into<anyhow::Error>) -> Self {
120 Self::Fetch(e.into())
121 }
122
123 pub fn io(e: impl Into<std::io::Error>) -> Self {
125 e.into().into()
126 }
127
128 fn io_kind(&self) -> std::io::ErrorKind {
129 use std::io::ErrorKind;
130 match self {
131 Error::Parse(_) => ErrorKind::InvalidData,
132 Error::Fetch(_) => ErrorKind::Other,
133 Error::Operation(_) => ErrorKind::Other,
134 Error::Consistency(_) => ErrorKind::InvalidData,
135 Error::Io(e) => e.kind(),
136 Error::ExtraInputLeft => ErrorKind::InvalidData,
137 Error::EndOfInput => ErrorKind::UnexpectedEof,
138 Error::AddressOutOfBounds => ErrorKind::Other,
139 Error::ResolutionMismatch => ErrorKind::InvalidData,
140 Error::FullHashMismatch => ErrorKind::InvalidData,
141 Error::DiscriminantOverflow => ErrorKind::InvalidData,
142 Error::Zero => ErrorKind::InvalidData,
143 Error::OutOfBounds => ErrorKind::InvalidData,
144 Error::UnsupportedLength => ErrorKind::FileTooLarge,
145 Error::Utf8(_) => ErrorKind::InvalidData,
146 Error::UnknownExtension => ErrorKind::Other,
147 Error::ExtensionType => ErrorKind::Other,
148 Error::Unimplemented => ErrorKind::Unsupported,
149 Error::HashNotFound => ErrorKind::NotFound,
150 Error::Interrupted => ErrorKind::Interrupted,
151 }
152 }
153}
154
155impl From<Error> for std::io::Error {
156 fn from(value: Error) -> Self {
157 match value {
158 Error::Io(e) => e,
159 e => Self::new(e.io_kind(), e),
160 }
161 }
162}
163
164pub type Result<T> = std::result::Result<T, Error>;