1use std::fmt;
4
5#[derive(Debug)]
7pub enum YamlError {
8 Io(std::io::Error),
10
11 Parse {
13 message: String,
15 line: Option<usize>,
17 column: Option<usize>,
19 },
20
21 KeyNotFound {
23 key: String,
25 available_keys: Vec<String>,
27 path: String,
29 },
30
31 TypeMismatch {
33 expected: String,
35 actual: String,
37 path: String,
39 },
40
41 InvalidIndex {
43 index: usize,
45 length: usize,
47 path: String,
49 },
50
51 InvalidOperation {
53 operation: String,
55 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
146pub type YamlResult<T> = Result<T, YamlError>;