|
|
@ -10,16 +10,33 @@ pub enum Error {
|
|
|
|
InvalidSectionName,
|
|
|
|
InvalidSectionName,
|
|
|
|
InvalidSectionData,
|
|
|
|
InvalidSectionData,
|
|
|
|
ParseError(Box<dyn std::error::Error>),
|
|
|
|
ParseError(Box<dyn std::error::Error>),
|
|
|
|
TryFromIntError, //
|
|
|
|
TryFromIntError,
|
|
|
|
LinkingError(Trace),
|
|
|
|
LinkingError(Trace),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// "backtrace" for error origin
|
|
|
|
// "backtrace" for error origin
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct Trace {
|
|
|
|
pub struct Trace {
|
|
|
|
origin: PathBuf,
|
|
|
|
pub code: u32, // specific trace code, should be >= 700
|
|
|
|
offset: u64, // 0 indicates unknown/invalid
|
|
|
|
pub message: &'static str,
|
|
|
|
source_info: Option<Box<dyn SourceInfo>>,
|
|
|
|
pub origin: PathBuf,
|
|
|
|
|
|
|
|
pub offset: u64, // 0 indicates unknown/invalid
|
|
|
|
|
|
|
|
pub source_info: Option<Box<dyn SourceInfo>>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
|
|
|
|
// used for programmatic input/output handling, IDE's etc.
|
|
|
|
|
|
|
|
pub fn code(&self) -> u32 {
|
|
|
|
|
|
|
|
match self {
|
|
|
|
|
|
|
|
Error::IOError(_) => 100,
|
|
|
|
|
|
|
|
Error::InvalidObjectType(_) => 200,
|
|
|
|
|
|
|
|
Error::InvalidSectionName => 300,
|
|
|
|
|
|
|
|
Error::InvalidSectionData => 400,
|
|
|
|
|
|
|
|
Error::ParseError(_) => 500,
|
|
|
|
|
|
|
|
Error::TryFromIntError => 600,
|
|
|
|
|
|
|
|
Error::LinkingError(trace) => trace.code,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub trait SourceInfo: Debug + Display {
|
|
|
|
pub trait SourceInfo: Debug + Display {
|
|
|
@ -42,12 +59,39 @@ impl From<std::num::TryFromIntError> for Error {
|
|
|
|
|
|
|
|
|
|
|
|
impl Display for Error {
|
|
|
|
impl Display for Error {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "TODO!")
|
|
|
|
write!(f, "[{}] ", self.code())?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match self {
|
|
|
|
|
|
|
|
Error::IOError(err) => write!(f, "IO error: {}", err),
|
|
|
|
|
|
|
|
Error::InvalidObjectType(ot) => write!(f, "Invalid object type: {}", ot),
|
|
|
|
|
|
|
|
Error::InvalidSectionName => write!(f, "Invalid section name"),
|
|
|
|
|
|
|
|
Error::InvalidSectionData => write!(f, "Invalid section data"),
|
|
|
|
|
|
|
|
Error::ParseError(err) => write!(f, "Parse error: {}", err),
|
|
|
|
|
|
|
|
Error::TryFromIntError => write!(f, "Integer conversion error"),
|
|
|
|
|
|
|
|
Error::LinkingError(trace) => write!(f, "Linking error: {}", trace),
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Display for Trace {
|
|
|
|
impl Display for Trace {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "TODO!")
|
|
|
|
let mut new_line = ""; // new line in case of previous info only
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(origin) = self.origin.to_str() {
|
|
|
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
|
|
|
write!(f, "\n\t{}", origin)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.offset > 0 {
|
|
|
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
|
|
|
write!(f, "\n@offset: {}", self.offset)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(si) = &self.source_info {
|
|
|
|
|
|
|
|
new_line = "\n";
|
|
|
|
|
|
|
|
write!(f, "\n{}", si)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
write!(f, "{}{}", new_line, self.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|