1 use serde::de::Error as DeError; 2 use serde::ser::Error as SerError; 3 use std::fmt::Display; 4 use thiserror::Error; 5 6 #[derive(Debug, Error)] 7 pub enum Error { 8 #[error("Expected token {token}, found {found}")] 9 UnexpectedToken { token: String, found: String }, 10 #[error("custom: {field}")] 11 Custom { field: String }, 12 #[error("unsupported operation: '{operation}'")] 13 UnsupportedOperation { operation: String }, 14 15 #[error("IO error: {source}")] 16 Io { 17 #[from] 18 source: ::std::io::Error, 19 }, 20 21 #[error("FromUtf8Error: {source}")] 22 FromUtf8Error { 23 #[from] 24 source: ::std::string::FromUtf8Error, 25 }, 26 27 #[error("ParseIntError: {source}")] 28 ParseIntError { 29 #[from] 30 source: ::std::num::ParseIntError, 31 }, 32 33 #[error("ParseFloatError: {source}")] 34 ParseFloatError { 35 #[from] 36 source: ::std::num::ParseFloatError, 37 }, 38 39 #[error("ParseBoolError: {source}")] 40 ParseBoolError { 41 #[from] 42 source: ::std::str::ParseBoolError, 43 }, 44 45 #[error("Syntax: {source}")] 46 Syntax { 47 #[from] 48 source: ::xml::reader::Error, 49 }, 50 } 51 52 pub type Result<T> = std::result::Result<T, Error>; 53 54 #[macro_export] 55 macro_rules! expect { 56 ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { 57 match $actual { 58 $($expected)|+ => $if_ok, 59 actual => Err($crate::Error::UnexpectedToken { 60 token: stringify!($($expected)|+).to_string(), 61 found: format!("{:?}",actual) 62 }) as Result<_> 63 } 64 } 65 } 66 67 #[cfg(debug_assertions)] 68 #[macro_export] 69 macro_rules! debug_expect { 70 ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { 71 match $actual { 72 $($expected)|+ => $if_ok, 73 actual => panic!( 74 "Internal error: Expected token {}, found {:?}", 75 stringify!($($expected)|+), 76 actual 77 ) 78 } 79 } 80 } 81 82 #[cfg(not(debug_assertions))] 83 #[macro_export] 84 macro_rules! debug_expect { 85 ($actual: expr, $($expected: pat)|+ => $if_ok: expr) => { 86 match $actual { 87 $($expected)|+ => $if_ok, 88 _ => unreachable!() 89 } 90 } 91 } 92 93 impl DeError for Error { custom<T: Display>(msg: T) -> Self94 fn custom<T: Display>(msg: T) -> Self { 95 Error::Custom { 96 field: msg.to_string(), 97 } 98 } 99 } 100 101 impl SerError for Error { custom<T: Display>(msg: T) -> Self102 fn custom<T: Display>(msg: T) -> Self { 103 Error::Custom { 104 field: msg.to_string(), 105 } 106 } 107 } 108