// rasm-core/src/lexer/err.rs
//
//! Ошибки лексического анализа.
use std::fmt::Display;

use crate::lexer::token::Span;

#[derive(Debug)]
pub enum LexerErrorKind {
    UnexpectedChar(char),
    InvalidFloat(String),
    InvalidInteger(String),
    UnterminatedString,
}

impl Display for LexerErrorKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match &self {
            Self::UnexpectedChar(ch) => write!(f, "unexpected char: '{ch}'"),
            Self::InvalidFloat(float) => write!(f, "invalid float: '{float}'"),
            Self::InvalidInteger(int) => write!(f, "invalid integer: '{int}'"),
            Self::UnterminatedString => write!(f, "unterminated string literal"),
        }
    }
}

#[derive(Debug)]
pub struct LexerError {
    pub kind: LexerErrorKind,
    pub pos: Span,
}

impl LexerError {
    pub fn new(kind: LexerErrorKind, pos: Span) -> Self {
        Self { kind, pos }
    }
}

impl Display for LexerError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.kind)
    }
}
