mirror of https://github.com/zkat/miette.git
153 lines
4.2 KiB
Rust
153 lines
4.2 KiB
Rust
extern crate alloc;
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
use crate::StdError as Error;
|
|
use alloc::boxed::Box;
|
|
use core::fmt::{self, Display};
|
|
#[cfg(feature = "std")]
|
|
use std::error::Error;
|
|
#[cfg(feature = "std")]
|
|
use std::io;
|
|
|
|
use crate::Diagnostic;
|
|
|
|
/**
|
|
Error enum for miette. Used by certain operations in the protocol.
|
|
*/
|
|
#[derive(Debug)]
|
|
pub enum MietteError {
|
|
/// Wrapper around [`io::Error`]. This is returned when something went
|
|
/// wrong while reading a [`SourceCode`](crate::SourceCode).
|
|
#[cfg(feature = "std")]
|
|
IoError(io::Error),
|
|
|
|
/// Returned when a [`SourceSpan`](crate::SourceSpan) extends beyond the
|
|
/// bounds of a given [`SourceCode`](crate::SourceCode).
|
|
OutOfBounds,
|
|
}
|
|
|
|
impl Display for MietteError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
#[cfg(feature = "std")]
|
|
MietteError::IoError(error) => write!(f, "{error}"),
|
|
MietteError::OutOfBounds => {
|
|
write!(f, "The given offset is outside the bounds of its Source")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error for MietteError {
|
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
match self {
|
|
#[cfg(feature = "std")]
|
|
MietteError::IoError(error) => error.source(),
|
|
MietteError::OutOfBounds => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl From<io::Error> for MietteError {
|
|
fn from(value: io::Error) -> Self {
|
|
Self::IoError(value)
|
|
}
|
|
}
|
|
|
|
impl Diagnostic for MietteError {
|
|
fn code<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
|
|
match self {
|
|
#[cfg(feature = "std")]
|
|
MietteError::IoError(_) => Some(Box::new("miette::io_error")),
|
|
MietteError::OutOfBounds => Some(Box::new("miette::span_out_of_bounds")),
|
|
}
|
|
}
|
|
|
|
fn help<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
|
|
match self {
|
|
#[cfg(feature = "std")]
|
|
MietteError::IoError(_) => None,
|
|
MietteError::OutOfBounds => Some(Box::new(
|
|
"Double-check your spans. Do you have an off-by-one error?",
|
|
)),
|
|
}
|
|
}
|
|
|
|
fn url<'a>(&'a self) -> Option<Box<dyn fmt::Display + 'a>> {
|
|
let crate_version = env!("CARGO_PKG_VERSION");
|
|
let variant = match self {
|
|
#[cfg(feature = "std")]
|
|
MietteError::IoError(_) => "#variant.IoError",
|
|
MietteError::OutOfBounds => "#variant.OutOfBounds",
|
|
};
|
|
Some(Box::new(alloc::format!(
|
|
"https://docs.rs/miette/{}/miette/enum.MietteError.html{}",
|
|
crate_version,
|
|
variant,
|
|
)))
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(crate) mod tests {
|
|
#[cfg(not(feature = "std"))]
|
|
use crate::StdError as Error;
|
|
use std::string::ToString;
|
|
|
|
use super::*;
|
|
|
|
#[derive(Debug)]
|
|
#[cfg(feature = "std")]
|
|
pub(crate) struct TestError(pub(crate) io::Error);
|
|
#[cfg(not(feature = "std"))]
|
|
pub(crate) struct TestError(pub(crate) &'static str);
|
|
|
|
impl Display for TestError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "testing, testing...")
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl Error for TestError {
|
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
Some(&self.0)
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
impl Error for TestError {
|
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
#[test]
|
|
fn io_error() {
|
|
let inner_error = io::Error::other("halt and catch fire");
|
|
let outer_error = TestError(inner_error);
|
|
let io_error = io::Error::other(outer_error);
|
|
|
|
let miette_error = MietteError::from(io_error);
|
|
|
|
assert_eq!(miette_error.to_string(), "testing, testing...");
|
|
assert_eq!(
|
|
miette_error.source().unwrap().to_string(),
|
|
"halt and catch fire"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn out_of_bounds() {
|
|
let miette_error = MietteError::OutOfBounds;
|
|
|
|
assert_eq!(
|
|
miette_error.to_string(),
|
|
"The given offset is outside the bounds of its Source"
|
|
);
|
|
assert_eq!(miette_error.source().map(ToString::to_string), None);
|
|
}
|
|
}
|