eure 0.1.9

Eure core library
Documentation
use eure_tree::{prelude::*, tree::LineNumbers};

use crate::tree::{WriteError, get_error_position_from_error};

pub struct WriteVisitor<'f, 't> {
    input: &'t str,
    line_numbers: LineNumbers<'t>,
    f: &'f mut dyn std::fmt::Write,
}

impl<'f, 't> WriteVisitor<'f, 't> {
    pub fn new(input: &'t str, f: &'f mut dyn std::fmt::Write) -> Self {
        Self {
            input,
            line_numbers: LineNumbers::new(input),
            f,
        }
    }
}

impl<F: CstFacade> CstVisitor<F> for WriteVisitor<'_, '_> {
    type Error = WriteError;

    fn then_construct_error(
        &mut self,
        node_data: Option<CstNode>,
        parent: CstNodeId,
        kind: NodeKind,
        error: CstConstructError,
        tree: &F,
    ) -> Result<(), WriteError> {
        if let Some((line, column)) =
            get_error_position_from_error(&self.line_numbers, &node_data, &error)
        {
            eprintln!("Syntax error at line {line}, column {column}: {error} expected {kind:?}");
        } else {
            eprintln!("Syntax error: {error} expected {kind:?}");
        }
        self.recover_error(node_data, parent, kind, tree)
    }

    fn visit_terminal(
        &mut self,
        _id: CstNodeId,
        _kind: TerminalKind,
        terminal: TerminalData,
        tree: &F,
    ) -> Result<(), WriteError> {
        match terminal {
            TerminalData::Input(input_span) => {
                write!(
                    self.f,
                    "{}",
                    &self.input[input_span.start as usize..input_span.end as usize]
                )?;
            }
            TerminalData::Dynamic(id) => {
                let str = tree
                    .dynamic_token(id)
                    .ok_or(WriteError::DynamicTokenNotFound { id })?;
                write!(self.f, "{str}")?;
            }
        }
        Ok(())
    }
}