//! DSL error type.
//!
//! We use `thiserror` so the error plays nicely with `anyhow::Error` at the
//! CLI boundary while still carrying structured location info.
use thiserror::Error;
#[derive(Debug, Error, PartialEq, Eq)]
pub enum DslError {
#[error("syntax error at column {column}: {message}")]
Syntax { column: usize, message: String },
#[error("unknown field `{field}` in filter expression")]
UnknownField { field: String },
#[error("invalid regex `/{pattern}/`: {reason}")]
InvalidRegex { pattern: String, reason: String },
#[error("operator `{op}` cannot be applied to {kind} value")]
TypeMismatch { op: &'static str, kind: &'static str },
}
pub type DslResult<T> = Result<T, DslError>;
impl DslError {
/// The 1-indexed column where this error occurred, or `None` for global
/// errors that aren't tied to a position.
pub fn column(&self) -> Option<usize> {
match self {
DslError::Syntax { column, .. } => Some(*column),
_ => None,
}
}
/// A short kind tag for exit-code mapping.
pub fn kind(&self) -> &'static str {
match self {
DslError::Syntax { .. } => "syntax",
DslError::UnknownField { .. } => "unknown_field",
DslError::InvalidRegex { .. } => "invalid_regex",
DslError::TypeMismatch { .. } => "type_mismatch",
}
}
}