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 {line}, column {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 '{key}' not found")?;
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 '{expected}', but found '{actual}'"
102                )?;
103                if !path.is_empty() {
104                    write!(f, " at path '{path}'")?;
105                }
106                Ok(())
107            }
108
109            YamlError::InvalidIndex {
110                index,
111                length,
112                path,
113            } => {
114                write!(
115                    f,
116                    "Index {index} is out of bounds (sequence has {length} elements)"
117                )?;
118                if !path.is_empty() {
119                    write!(f, " at path '{path}'")?;
120                }
121                Ok(())
122            }
123
124            YamlError::InvalidOperation { operation, reason } => {
125                write!(f, "Invalid operation '{operation}': {reason}")
126            }
127        }
128    }
129}
130
131impl std::error::Error for YamlError {
132    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
133        match self {
134            YamlError::Io(err) => Some(err),
135            _ => None,
136        }
137    }
138}
139
140impl From<std::io::Error> for YamlError {
141    fn from(err: std::io::Error) -> Self {
142        YamlError::Io(err)
143    }
144}
145
146/// Result type for yaml-edit operations
147pub type YamlResult<T> = Result<T, YamlError>;