1use std::fmt;
2
3#[non_exhaustive]
7#[derive(Debug, Clone)]
8pub struct ParseError {
9 pub message: String,
11 pub line: usize,
13 pub col: usize,
15}
16
17impl fmt::Display for ParseError {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(
20 f,
21 "ParseError at {}:{}: {}",
22 self.line, self.col, self.message
23 )
24 }
25}
26
27impl std::error::Error for ParseError {}
28
29#[non_exhaustive]
32#[derive(Debug, Clone)]
33pub struct ResolveError {
34 pub message: String,
36 pub path: String,
38 pub line: usize,
40 pub col: usize,
42}
43
44impl fmt::Display for ResolveError {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(
47 f,
48 "ResolveError at {}:{}: {} (path: {})",
49 self.line, self.col, self.message, self.path
50 )
51 }
52}
53
54impl ResolveError {
55 pub(crate) fn concat_type_mismatch(
60 left_type: &str,
61 right_type: &str,
62 line: usize,
63 col: usize,
64 ) -> Self {
65 ResolveError {
66 message: format!(
67 "value concatenation requires same-kind operands per HOCON S10; \
68 got {} + {}",
69 left_type, right_type
70 ),
71 path: String::new(),
72 line,
73 col,
74 }
75 }
76}
77
78impl std::error::Error for ResolveError {}
79
80#[non_exhaustive]
83#[derive(Debug, Clone)]
84pub struct ConfigError {
85 pub message: String,
87 pub path: String,
89}
90
91impl fmt::Display for ConfigError {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(f, "ConfigError: {} (path: {})", self.message, self.path)
94 }
95}
96
97impl std::error::Error for ConfigError {}
98
99impl ConfigError {
100 pub fn is_not_resolved(&self) -> bool {
115 self.message.starts_with("value is not resolved")
116 }
117}
118
119#[derive(Debug, Clone)]
126pub struct NotResolvedError {
127 pub path: String,
129}
130
131impl fmt::Display for NotResolvedError {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 write!(
134 f,
135 "value at path {:?} is not resolved (call resolve() before accessing values)",
136 self.path
137 )
138 }
139}
140
141impl std::error::Error for NotResolvedError {}
142
143#[non_exhaustive]
149#[derive(Debug)]
150pub enum HoconError {
151 Parse(ParseError),
153 Resolve(ResolveError),
155 Io(std::io::Error),
157 NotResolved(NotResolvedError),
160}
161
162impl fmt::Display for HoconError {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 match self {
165 HoconError::Parse(e) => write!(f, "{}", e),
166 HoconError::Resolve(e) => write!(f, "{}", e),
167 HoconError::Io(e) => write!(f, "I/O error: {}", e),
168 HoconError::NotResolved(e) => write!(f, "{}", e),
169 }
170 }
171}
172
173impl std::error::Error for HoconError {
174 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
175 match self {
176 HoconError::Parse(e) => Some(e),
177 HoconError::Resolve(e) => Some(e),
178 HoconError::Io(e) => Some(e),
179 HoconError::NotResolved(e) => Some(e),
180 }
181 }
182}
183
184impl From<ParseError> for HoconError {
185 fn from(e: ParseError) -> Self {
186 HoconError::Parse(e)
187 }
188}
189
190impl From<ResolveError> for HoconError {
191 fn from(e: ResolveError) -> Self {
192 HoconError::Resolve(e)
193 }
194}
195
196impl From<std::io::Error> for HoconError {
197 fn from(e: std::io::Error) -> Self {
198 HoconError::Io(e)
199 }
200}