Skip to main content

yaml_edit/
error.rs

1//! Error types for yaml-edit
2
3use std::fmt;
4
5/// Errors that can occur when working with YAML documents
6#[derive(Debug)]
7pub enum YamlError {
8    /// I/O error when reading or writing files
9    Io(std::io::Error),
10
11    /// Parse error when parsing YAML
12    Parse {
13        /// Error message describing what went wrong
14        message: String,
15        /// Line number where the error occurred (if available)
16        line: Option<usize>,
17        /// Column number where the error occurred (if available)
18        column: Option<usize>,
19    },
20
21    /// Key not found in mapping
22    KeyNotFound {
23        /// The key that was not found
24        key: String,
25        /// Available keys in the mapping (for helpful error messages)
26        available_keys: Vec<String>,
27        /// Path to the mapping where the key was searched
28        path: String,
29    },
30
31    /// Type mismatch - expected one type but got another
32    TypeMismatch {
33        /// Expected type (e.g., "mapping", "sequence", "scalar")
34        expected: String,
35        /// Actual type found
36        actual: String,
37        /// Path to the value with the type mismatch
38        path: String,
39    },
40
41    /// Invalid index for sequence access
42    InvalidIndex {
43        /// The index that was out of bounds
44        index: usize,
45        /// The actual length of the sequence
46        length: usize,
47        /// Path to the sequence
48        path: String,
49    },
50
51    /// Invalid operation for the given context
52    InvalidOperation {
53        /// Description of what operation was attempted
54        operation: String,
55        /// Why it's invalid
56        reason: String,
57    },
58}
59
60impl fmt::Display for YamlError {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        match self {
63            YamlError::Io(err) => write!(f, "I/O error: {}", err),
64
65            YamlError::Parse {
66                message,
67                line,
68                column,
69            } => {
70                write!(f, "Parse error")?;
71                if let (Some(line), Some(column)) = (line, column) {
72                    write!(f, " at line {}, column {}", line, column)?;
73                } else if let Some(line) = line {
74                    write!(f, " at line {}", line)?;
75                }
76                write!(f, ": {}", message)
77            }
78
79            YamlError::KeyNotFound {
80                key,
81                available_keys,
82                path,
83            } => {
84                write!(f, "Key '{}' not found", key)?;
85                if !path.is_empty() {
86                    write!(f, " at path '{}'", path)?;
87                }
88                if !available_keys.is_empty() {
89                    write!(f, ". Available keys: [{}]", available_keys.join(", "))?;
90                }
91                Ok(())
92            }
93
94            YamlError::TypeMismatch {
95                expected,
96                actual,
97                path,
98            } => {
99                write!(
100                    f,
101                    "Type mismatch: expected '{}', but found '{}'",
102                    expected, actual
103                )?;
104                if !path.is_empty() {
105                    write!(f, " at path '{}'", path)?;
106                }
107                Ok(())
108            }
109
110            YamlError::InvalidIndex {
111                index,
112                length,
113                path,
114            } => {
115                write!(
116                    f,
117                    "Index {} is out of bounds (sequence has {} elements)",
118                    index, length
119                )?;
120                if !path.is_empty() {
121                    write!(f, " at path '{}'", path)?;
122                }
123                Ok(())
124            }
125
126            YamlError::InvalidOperation { operation, reason } => {
127                write!(f, "Invalid operation '{}': {}", operation, reason)
128            }
129        }
130    }
131}
132
133impl std::error::Error for YamlError {
134    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
135        match self {
136            YamlError::Io(err) => Some(err),
137            _ => None,
138        }
139    }
140}
141
142impl From<std::io::Error> for YamlError {
143    fn from(err: std::io::Error) -> Self {
144        YamlError::Io(err)
145    }
146}
147
148/// Result type for yaml-edit operations
149pub type YamlResult<T> = Result<T, YamlError>;