#[derive(Debug, Clone, PartialEq)]
pub enum ErrorKind {
CoinInvalid,
CoinNotUnique,
CoinTooCheap,
TransactionInvalidSender,
TransactionEmpty,
TransactionBrokenGroup,
TransactionBrokenExt,
BlockBroken,
BlockOrderMismatch,
BlockValidatorMismatch,
BlockPreviousHashMismatch,
BlockOffsetMismatch,
BlockInvalidHash,
BlockInvalidHashComplexity,
Other,
}
#[macro_export]
macro_rules! validate {
($check:expr, $kind:ident) => (
if $check {
Ok::<(), crate::error::Error>(())
} else {
Err(crate::error::ErrorKind::$kind.into())
}
)
}
#[derive(Debug, Clone, PartialEq)]
pub struct Error {
kind: ErrorKind,
message: String,
}
impl Error {
pub fn new(kind: ErrorKind, message: String) -> Self {
Self { kind, message }
}
pub fn kind(&self) -> ErrorKind {
self.kind.clone()
}
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
impl From<ErrorKind> for Error {
fn from(uqoin_error_kind: ErrorKind) -> Error {
let message = format!("{:?}", uqoin_error_kind);
Error::new(uqoin_error_kind, message)
}
}
impl From<Error> for std::io::Error {
fn from(uqoin_error: Error) -> std::io::Error {
std::io::Error::new(std::io::ErrorKind::Other, uqoin_error.to_string())
}
}
impl From<ErrorKind> for std::io::Error {
fn from(uqoin_error_kind: ErrorKind) -> std::io::Error {
let uqoin_error = Error::from(uqoin_error_kind);
uqoin_error.into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let err = Error::new(
ErrorKind::CoinInvalid,
"E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
.to_string()
);
assert_eq!(err.kind(), ErrorKind::CoinInvalid);
assert_eq!(
err.to_string(),
"E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
);
}
#[test]
fn test_err_to_std() {
let err = Error::new(
ErrorKind::CoinInvalid,
"E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
.to_string()
);
let err_std: std::io::Error = err.into();
assert_eq!(err_std.kind(), std::io::ErrorKind::Other);
assert_eq!(
err_std.to_string(),
"E764663DA70C4805F07F733C2A782116C7492C70EE67DD39C5DDA817816B8AB2"
);
}
#[test]
fn test_kind_to_err() {
let kind = ErrorKind::CoinInvalid;
let err: Error = kind.into();
assert_eq!(err.kind(), ErrorKind::CoinInvalid);
assert_eq!(err.to_string(), "CoinInvalid");
}
#[test]
fn test_kind_to_err_str() {
let kind = ErrorKind::CoinInvalid;
let err_std: std::io::Error = kind.into();
assert_eq!(err_std.kind(), std::io::ErrorKind::Other);
assert_eq!(err_std.to_string(), "CoinInvalid");
}
#[test]
fn test_validate_macro() {
let result = validate!(true, CoinInvalid);
assert!(result.is_ok());
let result = validate!(false, CoinTooCheap);
assert!(result.is_err());
if let Err(e) = result {
assert_eq!(e.kind(), ErrorKind::CoinTooCheap);
}
}
}