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