ask-dracula-rs/src/error.rs

102 lines
2.2 KiB
Rust

pub type Source = Box<dyn std::error::Error>;
pub enum Kind
{
ParseProject,
NotAFile(std::path::PathBuf),
WriteFile(std::path::PathBuf),
RunVampire,
InterpretVampireOutput(String, String),
}
pub struct Error
{
pub kind: Kind,
pub source: Option<Source>,
}
impl Error
{
pub fn new(kind: Kind) -> Self
{
Self
{
kind,
source: None,
}
}
pub fn with<S: Into<Source>>(mut self, source: S) -> Self
{
self.source = Some(source.into());
self
}
pub fn new_parse_project<S: Into<Source>>(source: S) -> Self
{
Self::new(Kind::ParseProject).with(source)
}
pub fn new_not_a_file(path: std::path::PathBuf) -> Self
{
Self::new(Kind::NotAFile(path))
}
pub fn new_write_file<S: Into<Source>>(path: std::path::PathBuf, source: S) -> Self
{
Self::new(Kind::WriteFile(path)).with(source)
}
pub fn new_run_vampire<S: Into<Source>>(source: S) -> Self
{
Self::new(Kind::RunVampire).with(source)
}
pub fn new_interpret_vampire_output(stdout: String, stderr: String) -> Self
{
Self::new(Kind::InterpretVampireOutput(stdout, stderr))
}
}
impl std::fmt::Debug for Error
{
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{
match self.kind
{
Kind::ParseProject => write!(formatter, "could not parse project file")?,
Kind::NotAFile(ref file_path) => write!(formatter, "specified path is not a file ({})", file_path.display())?,
Kind::WriteFile(ref file_path) => write!(formatter, "could not write file ({})", file_path.display())?,
Kind::RunVampire => write!(formatter, "could not run Vampire")?,
Kind::InterpretVampireOutput(ref stdout, ref stderr) => write!(formatter, "could not interpret Vampire output\n\n======== stdout =========\n{}\n\n======== stderr =========\n{}", stdout, stderr)?,
}
if let Some(source) = &self.source
{
write!(formatter, "\nerror source: {}", source)?;
}
Ok(())
}
}
impl std::fmt::Display for Error
{
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{
write!(formatter, "{:?}", self)
}
}
impl std::error::Error for Error
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)>
{
match &self.source
{
Some(source) => Some(source.as_ref()),
None => None,
}
}
}