rich-err 0.1.0

A highly detailed error type for compilers, tracebacks, etc.
Documentation
use crate::span::Span;
use ariadne::ReportBuilder;

/// An additional error message associated with a specific area of the source code.
///
/// These are good for providing more context-sensitive error messages while keeping the actual
/// error type general-use.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Label {
    /// The message to display to the user.
    ///
    /// If left blank, no space is wasted on displaying it.
    pub message: String,
    /// The [byte span](Span) within the source code that the label should refer to.
    pub span: Span,
}

impl Label {
    /// Constructs a new label without a message.
    ///
    /// To add a message, use the [`with_message`](Label::with_message) method.
    pub const fn new(span: Span) -> Self {
        Self {
            message: String::new(),
            span,
        }
    }

    /// Adds a message to this label.
    ///
    /// If a message was already present, this overwrites it.
    pub fn with_message<S>(mut self, message: S) -> Self
    where
        S: ToString,
    {
        self.message = message.to_string();
        self
    }

    /// Adds this label to a [`ReportBuilder`].
    pub fn add_to<Source>(
        self,
        builder: &mut ReportBuilder<'_, (Source, Span)>,
        source_name: Source,
    ) where
        (Source, Span): ariadne::Span,
    {
        let label = ariadne::Label::new((source_name, self.span)).with_color(ariadne::Color::Red);
        builder.add_label(if !self.message.is_empty() {
            label.with_message(self.message)
        } else {
            label
        });
    }
}