1#[derive(Debug, Clone, PartialEq)]
35pub enum ErrorKind {
36 CoinInvalid,
37 CoinNotUnique,
38 CoinTooCheap,
39 TransactionInvalidSender,
40 TransactionEmpty,
41 TransactionBrokenGroup,
42 TransactionBrokenExt,
43 BlockBroken,
44 BlockOrderMismatch,
45 BlockValidatorMismatch,
46 BlockPreviousHashMismatch,
47 BlockOffsetMismatch,
48 BlockInvalidHash,
49 BlockInvalidHashComplexity,
50 BlockchainTruncate,
51 Other,
52}
53
54
55#[macro_export]
63macro_rules! validate {
64 ($check:expr, $kind:ident) => (
65 if $check {
66 Ok::<(), crate::error::Error>(())
67 } else {
68 Err(crate::error::ErrorKind::$kind.into())
69 }
70 )
71}
72
73
74#[derive(Debug, Clone, PartialEq)]
81pub struct Error {
82 kind: ErrorKind,
83 message: String,
84}
85
86
87impl Error {
88 pub fn new(kind: ErrorKind, message: String) -> Self {
90 Self { kind, message }
91 }
92
93 pub fn kind(&self) -> ErrorKind {
95 self.kind.clone()
96 }
97}
98
99
100impl std::error::Error for Error {}
101
102
103impl std::fmt::Display for Error {
104 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
105 write!(f, "{}", self.message)
106 }
107}
108
109
110impl From<ErrorKind> for Error {
111 fn from(uqoin_error_kind: ErrorKind) -> Error {
112 let message = format!("{:?}", uqoin_error_kind);
113 Error::new(uqoin_error_kind, message)
114 }
115}
116
117
118impl From<Error> for std::io::Error {
119 fn from(uqoin_error: Error) -> std::io::Error {
120 std::io::Error::new(std::io::ErrorKind::Other, uqoin_error.to_string())
121 }
122}
123
124
125impl From<ErrorKind> for std::io::Error {
126 fn from(uqoin_error_kind: ErrorKind) -> std::io::Error {
127 let uqoin_error = Error::from(uqoin_error_kind);
128 uqoin_error.into()
129 }
130}
131
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_new() {
139 let err = Error::new(
140 ErrorKind::CoinInvalid,
141 "E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
142 .to_string()
143 );
144
145 assert_eq!(err.kind(), ErrorKind::CoinInvalid);
146 assert_eq!(
147 err.to_string(),
148 "E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
149 );
150 }
151
152 #[test]
153 fn test_err_to_std() {
154 let err = Error::new(
155 ErrorKind::CoinInvalid,
156 "E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
157 .to_string()
158 );
159
160 let err_std: std::io::Error = err.into();
161
162 assert_eq!(err_std.kind(), std::io::ErrorKind::Other);
163 assert_eq!(
164 err_std.to_string(),
165 "E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
166 );
167 }
168
169 #[test]
170 fn test_kind_to_err() {
171 let kind = ErrorKind::CoinInvalid;
172 let err: Error = kind.into();
173 assert_eq!(err.kind(), ErrorKind::CoinInvalid);
174 assert_eq!(err.to_string(), "CoinInvalid");
175 }
176
177 #[test]
178 fn test_kind_to_err_str() {
179 let kind = ErrorKind::CoinInvalid;
180 let err_std: std::io::Error = kind.into();
181 assert_eq!(err_std.kind(), std::io::ErrorKind::Other);
182 assert_eq!(err_std.to_string(), "CoinInvalid");
183 }
184
185 #[test]
186 fn test_validate_macro() {
187 let result = validate!(true, CoinInvalid);
188 assert!(result.is_ok());
189
190 let result = validate!(false, CoinTooCheap);
191 assert!(result.is_err());
192 if let Err(e) = result {
193 assert_eq!(e.kind(), ErrorKind::CoinTooCheap);
194 }
195 }
196}