Skip to main content

miniconf_parser/
error.rs

1use std::fmt;
2
3use thiserror::Error;
4
5use crate::parser::Rule;
6
7/// Errors produced while parsing MiniConf documents.
8#[derive(Debug, Error)]
9pub enum MiniConfError {
10    /// Underlying pest error emitted when the grammar fails.
11    #[error("parse error: {0}")]
12    Pest(Box<pest::error::Error<Rule>>),
13    /// Higher-level semantic issue surfaced after the grammar matched.
14    #[error("{kind} on line {line}: {message}")]
15    Semantic {
16        /// Classification of the problem.
17        kind: ParseErrorKind,
18        /// 1-based line number where the issue originated.
19        line: usize,
20        /// Human-friendly description.
21        message: String,
22    },
23}
24
25impl MiniConfError {
26    /// Creates a semantic error for convenience.
27    pub(crate) fn semantic(kind: ParseErrorKind, line: usize, message: impl Into<String>) -> Self {
28        Self::Semantic {
29            kind,
30            line,
31            message: message.into(),
32        }
33    }
34}
35
36impl From<pest::error::Error<Rule>> for MiniConfError {
37    fn from(value: pest::error::Error<Rule>) -> Self {
38        Self::Pest(Box::new(value))
39    }
40}
41
42/// Enum describing semantic parsing problems.
43#[derive(Debug, Copy, Clone, Eq, PartialEq)]
44pub enum ParseErrorKind {
45    /// Duplicate key encountered inside a section.
46    DuplicateKey,
47    /// Value failed validation after the grammar matched.
48    InvalidValue,
49}
50
51impl fmt::Display for ParseErrorKind {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        match self {
54            Self::DuplicateKey => write!(f, "duplicate key"),
55            Self::InvalidValue => write!(f, "invalid value"),
56        }
57    }
58}