bitcoin_explorer/parser/
errors.rs1use bitcoin::hashes::hex::Error;
2use std::convert::{self, From};
3use std::error;
4use std::fmt;
5use std::io;
6use std::string;
7use std::sync;
8
9pub type OpResult<T> = Result<T, OpError>;
10
11#[derive(Debug)]
12pub struct OpError {
14 pub kind: OpErrorKind,
15 pub message: String,
16}
17
18impl OpError {
19 pub fn new(kind: OpErrorKind) -> Self {
20 OpError {
21 kind,
22 message: String::new(),
23 }
24 }
25
26 pub fn join_msg(mut self, msg: &str) -> Self {
28 self.message.push_str(msg);
29 OpError {
30 kind: self.kind,
31 message: self.message,
32 }
33 }
34}
35
36impl fmt::Display for OpError {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 if self.message.is_empty() {
39 write!(f, "{}", &self.kind)
40 } else {
41 write!(f, "{} {}", &self.message, &self.kind)
42 }
43 }
44}
45
46impl error::Error for OpError {
47 fn description(&self) -> &str {
48 self.message.as_ref()
49 }
50 fn cause(&self) -> Option<&dyn error::Error> {
51 self.kind.source()
52 }
53}
54
55#[derive(Debug)]
56pub enum OpErrorKind {
57 None,
58 IoError(io::Error),
59 Utf8Error(string::FromUtf8Error),
60 RuntimeError,
61 PoisonError,
62 SendError,
63}
64
65impl fmt::Display for OpErrorKind {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 match *self {
68 OpErrorKind::IoError(ref err) => write!(f, "I/O Error: {}", err),
69 OpErrorKind::Utf8Error(ref err) => write!(f, "Utf8 Conversion: {}", err),
70 ref err @ OpErrorKind::PoisonError => write!(f, "Threading Error: {}", err),
71 ref err @ OpErrorKind::SendError => write!(f, "Sync: {}", err),
72 ref err @ OpErrorKind::RuntimeError => write!(f, "RuntimeError: {}", err),
73 OpErrorKind::None => write!(f, ""),
74 }
75 }
76}
77
78impl error::Error for OpErrorKind {
79 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
80 match *self {
81 OpErrorKind::IoError(ref err) => Some(err),
82 OpErrorKind::Utf8Error(ref err) => Some(err),
83 ref err @ OpErrorKind::PoisonError => Some(err),
84 ref err @ OpErrorKind::SendError => Some(err),
85 _ => None,
86 }
87 }
88}
89
90impl From<io::Error> for OpError {
91 fn from(err: io::Error) -> Self {
92 Self::new(OpErrorKind::IoError(err))
93 }
94}
95
96impl From<bitcoin::consensus::encode::Error> for OpError {
97 fn from(_: bitcoin::consensus::encode::Error) -> Self {
98 Self::from("block decode error")
99 }
100}
101
102impl From<bitcoin::hashes::hex::Error> for OpError {
103 fn from(_: Error) -> Self {
104 Self::from("not a valid hash")
105 }
106}
107
108impl From<bitcoin::hashes::Error> for OpError {
109 fn from(_: bitcoin::hashes::Error) -> Self {
110 Self::from("bitcoin_hash error")
111 }
112}
113
114impl convert::From<i32> for OpError {
115 fn from(err_code: i32) -> Self {
116 Self::from(io::Error::from_raw_os_error(err_code))
117 }
118}
119
120impl convert::From<&str> for OpError {
121 fn from(err: &str) -> Self {
122 Self::new(OpErrorKind::None).join_msg(err)
123 }
124}
125
126impl<T> convert::From<sync::PoisonError<T>> for OpError {
127 fn from(_: sync::PoisonError<T>) -> Self {
128 Self::new(OpErrorKind::PoisonError)
129 }
130}
131
132impl<T> convert::From<sync::mpsc::SendError<T>> for OpError {
133 fn from(_: sync::mpsc::SendError<T>) -> Self {
134 Self::new(OpErrorKind::SendError)
135 }
136}
137
138impl convert::From<string::FromUtf8Error> for OpError {
139 fn from(err: string::FromUtf8Error) -> Self {
140 Self::new(OpErrorKind::Utf8Error(err))
141 }
142}
143
144impl convert::From<leveldb::error::Error> for OpError {
145 fn from(err: leveldb::error::Error) -> Self {
146 Self::from(err.to_string().as_ref())
147 }
148}