use crate::FQNameBuf;
use nom::Needed;
use std::backtrace::Backtrace;
use std::fmt::{Debug, Display, Formatter};
use std::io;
use std::path::PathBuf;
pub struct Error {
kind: ErrorKind,
backtrace: Backtrace,
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:#}", self)
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if f.alternate() {
write!(f, "{} at\n{}", self.kind, self.backtrace)
} else {
write!(f, "{}", self.kind)
}
}
}
impl std::error::Error for Error {}
impl Error {
pub fn new<E: Into<ErrorKind>>(kind: E) -> Self {
Self {
kind: kind.into(),
backtrace: Backtrace::capture(),
}
}
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
}
impl<E: Into<ErrorKind>> From<E> for Error {
fn from(error: E) -> Self {
let kind = error.into();
Self {
kind,
backtrace: Backtrace::capture(),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ErrorKind {
#[error("No class found for path {0:?}")]
NoClassFound(FQNameBuf),
#[error("Unsupported entry in classpath: {0:?}")]
UnsupportedEntry(PathBuf),
#[error("{0} is not a known constant pool tag")]
UnknownConstantPoolInfoTag(u8),
#[error(transparent)]
IoError(#[from] io::Error),
#[error("Missing {:?} bytes", 0)]
MissingBytes(Needed),
#[error(transparent)]
NomError {
kind: nom::Err<nom::error::Error<Vec<u8>>>,
},
#[error(transparent)]
ZipError(#[from] zip::result::ZipError),
#[error("adding inheritance of {0} failed")]
AddingInheritanceFailed(FQNameBuf),
}
impl<'a> From<nom::Err<nom::error::Error<&'a [u8]>>> for ErrorKind {
fn from(e: nom::Err<nom::error::Error<&'a [u8]>>) -> Self {
Self::NomError { kind: e.to_owned() }
}
}