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
use crate::item::SourceLocation;
use crate::confpath::ConfPath;
use std::rc::Rc;
#[derive(Debug)]
pub enum ConfigError {
ValueNotFound(ConfPath),
TooManyValues(usize, ConfPath, Vec<Rc<dyn SourceLocation>>),
NotEnoughValues(usize, ConfPath),
ValueError(Box<dyn std::error::Error>, Rc<dyn SourceLocation>),
MultipleReferences
}
fn too_many_values_formater(f: &mut std::fmt::Formatter, max_num: usize, key: &ConfPath, source_locations: &[Rc<dyn SourceLocation>]) -> std::fmt::Result {
write!(f, "More than {} value found for key {}@[", max_num, key)?;
for (i, source_location) in source_locations.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "'{}'", source_location)?;
};
write!(f, "]")
}
impl std::fmt::Display for ConfigError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::ValueNotFound(key) => write!(f, "Missing value for config key '{}'.", key),
Self::TooManyValues(max_num, key, source_locations) => too_many_values_formater(f, *max_num, key, source_locations),
Self::NotEnoughValues(min_num, key) => write!(f, "Key '{}' must have at least {} values.", key, min_num),
Self::ValueError(error, source_location) => write!(f, "{}@'{}'", error, source_location),
Self::MultipleReferences => write!(f, "Internal error. Multiple references to same config pipeline.")
}
}
}
impl std::error::Error for ConfigError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ValueError(error, _) => Some(error.as_ref()),
_ => None
}
}
}
impl ConfigError {
pub fn from_error<E: std::error::Error + 'static>(error: E, source_location: Rc<dyn SourceLocation>) -> Self {
ConfigError::ValueError(Box::from(error), source_location)
}
}