You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
2.3 KiB

use super::*;
use std::{
error,
fmt,
io,
};
#[derive(Debug, Clone)]
pub enum Mode
{
Ignore,
Warn,
Cancel,
Terminate,
}
impl Mode
{
pub fn handle<E: error::Error,T>(&self, err: Result<T,E>) -> Result<Option<T>,E>
{
match err {
Err(err) => {
match self {
Self::Warn => println!("[WARN]: {}", err),
Self::Cancel => return Err(err),
Self::Terminate => Err(err).expect("Terminating on error"),
_ => (),
};
Ok(None)
},
Ok(ok) => Ok(Some(ok)),
}
}
}
#[derive(Debug)]
pub enum Error
{
Unknown,
Arch(Option<&'static str>),
IO(io::Error),
Size{expected: usize, got: usize},
ArgParse(arg::Error),
Internal(Box<(dyn error::Error + std::marker::Send)>),
}
impl error::Error for Error
{
fn source(&self) -> Option<&(dyn error::Error + 'static)>
{
Some(match &self {
Error::IO(e) => e,
_ => return None,
})
}
}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "error: ")?;
match self {
Self::ArgParse(arg) => write!(f, "arg: {}", arg),
Self::Arch(Some(expl)) => write!(f, "bad arch: {}", expl),
Self::Arch(_) => write!(f, "bad arch (this is usually an indicator of an improperly compiled binary.)"),
Self::Size{expected, got} => write!(f, "size mismatch: expected {}, got {}", expected, got),
Self::IO(e) => write!(f, "io: {}", e),
Error::Internal(e) => write!(f, "internal: {}", e),
_ => write!(f, "unknown"),
}
}
}
impl From<Box<(dyn error::Error + std::marker::Send)>> for Error
{
fn from(bx: Box<(dyn error::Error + std::marker::Send)>) -> Self
{
Self::Internal(bx)
}
}
impl From<io::Error> for Error
{
fn from(er: io::Error) -> Self
{
Self::IO(er)
}
}
impl From<arg::Error> for Error
{
fn from(er: arg::Error) -> Self
{
Self::ArgParse(er)
}
}
// Helper functions:
/// Return error for size if needed
#[inline]
pub fn check_size(expected: usize, got: usize) -> Result<(), Error>
{
if expected == got {
Ok(())
} else {
Err(Error::Size{expected, got})
}
}
/// Return an `Error::Internal` if needed.
#[inline]
pub fn internal<E: error::Error + std::marker::Send + 'static, T>(from: Result<T,E>) -> Result<T,Error>
{
from.or_else(move |e| Err(Error::Internal(Box::new(e))))
}