cmakefmt/error.rs
1// SPDX-FileCopyrightText: Copyright 2026 Puneet Matharu
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5use thiserror::Error;
6
7/// Structured config/spec deserialization failure metadata used for
8/// user-facing diagnostics.
9#[derive(Debug, Clone)]
10pub struct FileParseError {
11 /// Parser format name, such as `TOML` or `YAML`.
12 pub format: &'static str,
13 /// Human-readable parser message.
14 pub message: Box<str>,
15 /// Optional 1-based line number.
16 pub line: Option<usize>,
17 /// Optional 1-based column number.
18 pub column: Option<usize>,
19}
20
21/// Errors that can be returned by parsing, config loading, spec loading, or
22/// formatting operations.
23#[derive(Debug, Error)]
24pub enum Error {
25 /// A syntax error reported by the CMake parser.
26 #[error("parse error: {0}")]
27 Parse(#[from] Box<pest::error::Error<crate::parser::Rule>>),
28
29 /// A parser error annotated with source text and line-offset context.
30 #[error("parse error in {display_name}: {source}")]
31 ParseContext {
32 /// Human-facing source name, for example a path or `<stdin>`.
33 display_name: String,
34 /// The source text that failed to parse.
35 source_text: Box<str>,
36 /// The 1-based source line number where this parser chunk started.
37 start_line: usize,
38 /// Whether earlier barrier/fence handling affected how this chunk was parsed.
39 barrier_context: bool,
40 /// The underlying pest parser error.
41 source: Box<pest::error::Error<crate::parser::Rule>>,
42 },
43
44 /// A user config parse error.
45 #[error("config error in {path}: {source_message}")]
46 Config {
47 /// The config file that failed to deserialize.
48 path: std::path::PathBuf,
49 /// Structured parser details for the failure.
50 details: FileParseError,
51 /// Cached display string used by `thiserror`.
52 source_message: Box<str>,
53 },
54
55 /// A built-in or user override spec parse error.
56 #[error("spec error in {path}: {source_message}")]
57 Spec {
58 /// The spec file that failed to deserialize.
59 path: std::path::PathBuf,
60 /// Structured parser details for the failure.
61 details: FileParseError,
62 /// Cached display string used by `thiserror`.
63 source_message: Box<str>,
64 },
65
66 /// A filesystem or stream I/O failure.
67 #[error("I/O error: {0}")]
68 Io(#[from] std::io::Error),
69
70 /// A higher-level formatter or CLI error that does not fit another
71 /// structured variant.
72 #[error("formatter error: {0}")]
73 Formatter(String),
74}
75
76/// Convenience alias for crate-level results.
77pub type Result<T> = std::result::Result<T, Error>;
78
79impl Error {
80 /// Attach a human-facing source name to a contextual parser error.
81 pub fn with_display_name(self, display_name: impl Into<String>) -> Self {
82 match self {
83 Self::ParseContext {
84 source_text,
85 start_line,
86 barrier_context,
87 source,
88 ..
89 } => Self::ParseContext {
90 display_name: display_name.into(),
91 source_text,
92 start_line,
93 barrier_context,
94 source,
95 },
96 other => other,
97 }
98 }
99}