fabaccess-bffh/bffhd/error.rs

98 lines
2.1 KiB
Rust
Raw Normal View History

2022-07-11 12:14:49 +02:00
use miette::{Diagnostic, LabeledSpan, Severity, SourceCode};
use std::error;
use std::fmt::{Display, Formatter};
use std::io;
2022-06-02 17:46:26 +02:00
use thiserror::Error;
2022-07-11 12:14:49 +02:00
pub trait Description {
const DESCRIPTION: Option<&'static str> = None;
const CODE: &'static str;
const HELP: Option<&'static str> = None;
const URL: Option<&'static str> = None;
}
2022-03-16 18:10:59 +01:00
2022-07-11 12:14:49 +02:00
pub fn wrap<D: Description>(error: Source) -> Error {
Error::new::<D>(error)
}
#[derive(Debug, Error, Diagnostic)]
pub enum Source {
#[error("io error occured")]
Io(
#[source]
#[from]
io::Error,
),
}
2020-02-14 12:20:17 +01:00
#[derive(Debug)]
2022-07-11 12:14:49 +02:00
pub struct Error {
description: Option<&'static str>,
code: &'static str,
severity: Option<Severity>,
help: Option<&'static str>,
url: Option<&'static str>,
source: Source,
}
2022-07-11 12:14:49 +02:00
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.source, f)
}
}
2022-06-02 17:46:26 +02:00
2022-07-11 12:14:49 +02:00
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(&self.source)
}
2022-06-02 17:46:26 +02:00
2022-07-11 12:14:49 +02:00
fn description(&self) -> &str {
if let Some(desc) = self.description {
desc
} else {
self.source.description()
}
2020-05-04 13:22:14 +02:00
}
}
2022-07-11 12:14:49 +02:00
impl Error {
pub fn new<D: Description>(source: Source) -> Self {
Self {
description: D::DESCRIPTION,
code: D::CODE,
severity: source.severity(),
help: D::HELP,
url: D::URL,
source,
}
}
}
2022-07-11 12:14:49 +02:00
impl miette::Diagnostic for Error {
2022-06-02 17:46:26 +02:00
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
2022-07-11 12:14:49 +02:00
Some(Box::new(self.code))
}
2022-06-02 17:46:26 +02:00
fn severity(&self) -> Option<Severity> {
2022-07-11 12:14:49 +02:00
self.severity
2022-06-02 17:46:26 +02:00
}
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
2022-07-11 12:14:49 +02:00
self.help.map(|r| {
let b: Box<dyn Display + 'a> = Box::new(r);
b
})
2022-06-02 17:46:26 +02:00
}
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
2022-07-11 12:14:49 +02:00
self.url.map(|r| {
let b: Box<dyn Display + 'a> = Box::new(r);
b
})
2020-02-18 16:55:19 +01:00
}
2022-06-02 17:46:26 +02:00
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
2022-07-11 12:14:49 +02:00
Some(&self.source)
2020-09-10 10:39:46 +02:00
}
}