rich-err 0.1.0

A highly detailed error type for compilers, tracebacks, etc.
Documentation
//! [Note]s provide a clean and easy way to make error messages more useful to the user.

use crate::span::Span;
use ariadne::ReportBuilder;

/// Specifies a [note](Note)'s kind.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum NoteKind {
    /// An ordinary note.
    ///
    /// These are useful for statements that add context to an error.
    #[default]
    Note,
    /// A note designed to assist the user.
    ///
    /// These are useful for suggestions that would help the user address the error.
    Help,
}

/// A message meant to provide extra context and/or assistance within an error message.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Note {
    /// What kind of note this is.
    ///
    /// This is used to customize the error reporting when [`Note::add_to`] is inevitably called.
    pub kind: NoteKind,
    /// The note's contents.
    pub message: String,
}

impl Note {
    /// Creates a new note with the given message.
    ///
    /// # Examples
    ///
    /// ```
    /// # use rich_err::note::{Note, NoteKind};
    /// assert_eq!(
    ///     Note::new_note("foo"),
    ///     Note {
    ///         kind: NoteKind::Note,
    ///         message: "foo".to_string(),
    ///     },
    /// );
    /// ```
    pub fn new_note<S>(message: S) -> Self
    where
        S: ToString,
    {
        Self {
            kind: NoteKind::Note,
            message: message.to_string(),
        }
    }

    /// Creates a new note with the given help message.
    ///
    /// # Examples
    ///
    /// ```
    /// # use rich_err::note::{Note, NoteKind};
    /// assert_eq!(
    ///     Note::new_help("foo"),
    ///     Note {
    ///         kind: NoteKind::Help,
    ///         message: "foo".to_string(),
    ///     },
    /// );
    /// ```
    pub fn new_help<S>(message: S) -> Self
    where
        S: ToString,
    {
        Self {
            kind: NoteKind::Help,
            message: message.to_string(),
        }
    }

    /// Adds this note to a [`ReportBuilder`].
    pub fn add_to<Source>(self, builder: &mut ReportBuilder<'_, (Source, Span)>)
    where
        (Source, Span): ariadne::Span,
    {
        match self.kind {
            NoteKind::Note => builder.add_note(self.message),
            NoteKind::Help => builder.add_help(self.message),
        }
    }
}