target_spec_miette/
lib.rs#![warn(missing_docs)]
#![forbid(unsafe_code)]
#![cfg_attr(doc_cfg, feature(doc_cfg, doc_auto_cfg))]
use miette::{Diagnostic, LabeledSpan, SourceCode, SourceOffset, SourceSpan};
use std::{error::Error as StdError, fmt};
use target_spec::errors::{
CustomTripleCreateError, Error as TargetSpecError, ExpressionParseError, PlainStringParseError,
TripleParseError,
};
pub trait IntoMietteDiagnostic {
type IntoDiagnostic;
fn into_diagnostic(self) -> Self::IntoDiagnostic;
}
impl IntoMietteDiagnostic for TargetSpecError {
type IntoDiagnostic = Box<dyn Diagnostic + Send + Sync + 'static>;
fn into_diagnostic(self) -> Self::IntoDiagnostic {
match self {
Self::InvalidExpression(error) => Box::new(error.into_diagnostic()),
Self::InvalidTargetSpecString(error) => Box::new(error.into_diagnostic()),
Self::UnknownPlatformTriple(error) => Box::new(error.into_diagnostic()),
#[allow(deprecated)]
Self::CustomTripleCreate(error) => Box::new(error.into_diagnostic()),
Self::CustomPlatformCreate(error) => Box::new(error.into_diagnostic()),
other => Box::<dyn Diagnostic + Send + Sync + 'static>::from(other.to_string()),
}
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct ExpressionParseDiagnostic(ExpressionParseError);
impl ExpressionParseDiagnostic {
pub fn new(error: ExpressionParseError) -> Self {
Self(error)
}
}
impl fmt::Debug for ExpressionParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for ExpressionParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl StdError for ExpressionParseDiagnostic {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.0.source()
}
}
impl Diagnostic for ExpressionParseDiagnostic {
fn source_code(&self) -> Option<&dyn SourceCode> {
Some(&self.0.input)
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
let label = LabeledSpan::new_with_span(Some(self.0.kind.to_string()), self.0.span.clone());
Some(Box::new(std::iter::once(label)))
}
}
impl IntoMietteDiagnostic for ExpressionParseError {
type IntoDiagnostic = ExpressionParseDiagnostic;
fn into_diagnostic(self) -> Self::IntoDiagnostic {
ExpressionParseDiagnostic::new(self)
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct TripleParseDiagnostic {
error: TripleParseError,
triple_str: String,
}
impl TripleParseDiagnostic {
pub fn new(error: TripleParseError) -> Self {
let triple_str = error.triple_str().to_owned();
Self { error, triple_str }
}
}
impl fmt::Debug for TripleParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.error, f)
}
}
impl fmt::Display for TripleParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.error, f)
}
}
impl StdError for TripleParseDiagnostic {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.error.source()
}
}
impl Diagnostic for TripleParseDiagnostic {
fn source_code(&self) -> Option<&dyn SourceCode> {
Some(&self.triple_str as &dyn SourceCode)
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
let label = LabeledSpan::new_with_span(
Some(
self.error
.source()
.expect("TripleParseError always returns a source")
.to_string(),
),
(0, self.triple_str.len()),
);
Some(Box::new(std::iter::once(label)))
}
}
impl IntoMietteDiagnostic for TripleParseError {
type IntoDiagnostic = TripleParseDiagnostic;
fn into_diagnostic(self) -> Self::IntoDiagnostic {
TripleParseDiagnostic::new(self)
}
}
#[derive(Clone, PartialEq, Eq)]
pub struct PlainStringParseDiagnostic {
error: PlainStringParseError,
input: String,
}
impl PlainStringParseDiagnostic {
pub fn new(error: PlainStringParseError) -> Self {
let input = error.input.clone();
Self { error, input }
}
}
impl fmt::Debug for PlainStringParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.error, f)
}
}
impl fmt::Display for PlainStringParseDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("invalid triple identifier")
}
}
impl StdError for PlainStringParseDiagnostic {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.error.source()
}
}
impl Diagnostic for PlainStringParseDiagnostic {
fn source_code(&self) -> Option<&dyn SourceCode> {
Some(&self.input as &dyn SourceCode)
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
let label = LabeledSpan::new_with_span(
Some("character must be alphanumeric, -, _ or .".to_owned()),
self.error.span(),
);
Some(Box::new(std::iter::once(label)))
}
}
impl IntoMietteDiagnostic for PlainStringParseError {
type IntoDiagnostic = PlainStringParseDiagnostic;
fn into_diagnostic(self) -> Self::IntoDiagnostic {
PlainStringParseDiagnostic::new(self)
}
}
impl IntoMietteDiagnostic for CustomTripleCreateError {
type IntoDiagnostic = CustomTripleCreateDiagnostic;
fn into_diagnostic(self) -> Self::IntoDiagnostic {
CustomTripleCreateDiagnostic::new(self)
}
}
pub struct CustomTripleCreateDiagnostic(CustomTripleCreateError);
impl CustomTripleCreateDiagnostic {
pub fn new(error: CustomTripleCreateError) -> Self {
Self(error)
}
}
impl fmt::Debug for CustomTripleCreateDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for CustomTripleCreateDiagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl StdError for CustomTripleCreateDiagnostic {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.0.source()
}
}
impl Diagnostic for CustomTripleCreateDiagnostic {
fn source_code(&self) -> Option<&dyn SourceCode> {
self.0.input_string().map(|input| input as &dyn SourceCode)
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
let input = self.0.input()?;
let (line, column) = self.0.line_and_column()?;
let source_offset = SourceOffset::from_location(input, line, column);
let span = SourceSpan::new(source_offset, 0);
let label = LabeledSpan::new_with_span(self.0.label(), span);
Some(Box::new(std::iter::once(label)))
}
}