ripex 0.3.0

Multi-language structural parsing and fact extraction.
Documentation
use crate::diagnostics::error::ParseError;
use crate::diagnostics::Severity;

#[derive(Debug, Clone)]
pub struct Diagnostic {
    pub severity: Severity,
    pub error: ParseError,
}

impl Diagnostic {
    pub fn new(severity: Severity, error: ParseError) -> Self {
        Diagnostic { severity, error }
    }

    pub fn error(error: ParseError) -> Self {
        Diagnostic::new(Severity::Error, error)
    }

    pub fn warning(error: ParseError) -> Self {
        Diagnostic::new(Severity::Warning, error)
    }
}

impl std::fmt::Display for Diagnostic {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let level = match self.severity {
            Severity::Error => "error",
            Severity::Warning => "warning",
            Severity::Info => "info",
            Severity::Hint => "hint",
        };
        write!(f, "[{}] {}", level, self.error)
    }
}

#[derive(Debug, Clone)]
pub struct DiagnosticReporter {
    diagnostics: Vec<Diagnostic>,
}

impl DiagnosticReporter {
    pub fn new() -> Self {
        DiagnosticReporter {
            diagnostics: Vec::new(),
        }
    }

    pub fn report(&mut self, diagnostic: Diagnostic) {
        self.diagnostics.push(diagnostic);
    }

    pub fn report_error(&mut self, error: ParseError) {
        self.report(Diagnostic::error(error));
    }

    pub fn report_warning(&mut self, error: ParseError) {
        self.report(Diagnostic::warning(error));
    }

    pub fn has_errors(&self) -> bool {
        self.diagnostics.iter().any(|d| d.severity.is_error())
    }

    pub fn errors(&self) -> impl Iterator<Item = &Diagnostic> {
        self.diagnostics.iter()
    }

    pub fn into_inner(self) -> Vec<Diagnostic> {
        self.diagnostics
    }

    pub fn extend(&mut self, other: impl IntoIterator<Item = Diagnostic>) {
        self.diagnostics.extend(other);
    }
}

impl Default for DiagnosticReporter {
    fn default() -> Self {
        DiagnosticReporter::new()
    }
}

impl IntoIterator for DiagnosticReporter {
    type Item = Diagnostic;
    type IntoIter = std::vec::IntoIter<Diagnostic>;

    fn into_iter(self) -> Self::IntoIter {
        self.diagnostics.into_iter()
    }
}