use std::num::ParseFloatError;

use thiserror_no_std::Error;

use super::{
    CommandError, PestError,
    formatting::FormatError,
    predicates::{BitwiseError, OpError},
    value::{MethodError, RuntimeError, ValError},
    variables::VariableError,
};

#[derive(Error, Debug, PartialEq, Clone)]
#[error("PestError: {0}")]
pub enum ParserError {
    PestError(String),

    #[error("ValError: {0}")]
    ValError(ValError),

    #[error("VariableError: {0}")]
    VariableError(VariableError),

    #[error("OperatorError: {0}")]
    OpError(OpError),

    #[error("MethodError: {0}")]
    MethodError(MethodError),

    #[error("CommandError: {0}")]
    CommandError(CommandError),

    #[error("BitwiseError: {0}")]
    BitwiseError(BitwiseError),

    #[error("RuntimeError: {0}")]
    RuntimeError(RuntimeError),

    #[error("ParseFloatError: {0}")]
    ParseFloatError(ParseFloatError),

    #[error("NotImplementedError: {0}")]
    NotImplemented(String),

    #[error("FormatError: {0}")]
    FormatError(FormatError),

    #[error("Skip")]
    Skip,
}

impl From<PestError> for ParserError {
    fn from(value: PestError) -> Self {
        Self::PestError(value.to_string())
    }
}

impl From<ValError> for ParserError {
    fn from(value: ValError) -> Self {
        Self::ValError(value)
    }
}

impl From<VariableError> for ParserError {
    fn from(value: VariableError) -> Self {
        Self::VariableError(value)
    }
}

impl From<OpError> for ParserError {
    fn from(value: OpError) -> Self {
        Self::OpError(value)
    }
}

impl From<MethodError> for ParserError {
    fn from(value: MethodError) -> Self {
        Self::MethodError(value)
    }
}

impl From<CommandError> for ParserError {
    fn from(value: CommandError) -> Self {
        Self::CommandError(value)
    }
}

impl From<BitwiseError> for ParserError {
    fn from(value: BitwiseError) -> Self {
        Self::BitwiseError(value)
    }
}

impl From<RuntimeError> for ParserError {
    fn from(value: RuntimeError) -> Self {
        Self::RuntimeError(value)
    }
}

impl std::error::Error for ParserError {}

impl From<ParseFloatError> for ParserError {
    fn from(value: ParseFloatError) -> Self {
        Self::ParseFloatError(value)
    }
}

impl From<FormatError> for ParserError {
    fn from(value: FormatError) -> Self {
        Self::FormatError(value)
    }
}
