Skip to main content

dotlyte/
errors.rs

1//! Error types for DOTLYTE v2.
2
3use std::fmt;
4use thiserror::Error;
5
6/// All possible DOTLYTE errors.
7#[derive(Error, Debug)]
8pub enum DotlyteError {
9    /// A required key was not found.
10    #[error("Required config key '{key}' is missing.{}", format_sources(.sources_checked))]
11    MissingKey {
12        key: String,
13        sources_checked: Vec<String>,
14    },
15
16    /// A config file has invalid syntax.
17    #[error("Parse error in {file}: {message}")]
18    ParseError { file: String, message: String },
19
20    /// An explicitly specified file was not found or unreadable.
21    #[error("File error for '{file}': {message}")]
22    FileError { file: String, message: String },
23
24    /// Schema validation failed.
25    #[error("Schema validation failed with {} violation(s): {}", .violations.len(), format_violations(.violations))]
26    ValidationError { violations: Vec<SchemaViolation> },
27
28    /// Variable interpolation error.
29    #[error("Interpolation error for '${{{{{}}}}}': {message}", .variable)]
30    InterpolationError { variable: String, message: String },
31
32    /// Decryption error.
33    #[error("Decryption error: {message}")]
34    DecryptionError { message: String },
35
36    /// An I/O error occurred.
37    #[error("I/O error: {0}")]
38    Io(#[from] std::io::Error),
39}
40
41/// A single schema validation failure.
42#[derive(Debug, Clone)]
43pub struct SchemaViolation {
44    pub key: String,
45    pub message: String,
46    pub rule: String,
47}
48
49impl fmt::Display for SchemaViolation {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "{}: {} ({})", self.key, self.message, self.rule)
52    }
53}
54
55/// Result alias for DOTLYTE operations.
56pub type Result<T> = std::result::Result<T, DotlyteError>;
57
58fn format_sources(sources: &[String]) -> String {
59    if sources.is_empty() {
60        String::new()
61    } else {
62        format!(" Sources checked: {}", sources.join(", "))
63    }
64}
65
66fn format_violations(violations: &[SchemaViolation]) -> String {
67    violations
68        .iter()
69        .map(|v| v.to_string())
70        .collect::<Vec<_>>()
71        .join("; ")
72}