-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
configuration_error.rs
130 lines (122 loc) · 4.95 KB
/
configuration_error.rs
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
use std::fmt;
/// When implementing the configure method of the Rule trait, the method returns a result that uses
/// this error type.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum RuleConfigurationError {
/// When a rule gets an unknown property. The string should be the unknown field name.
UnexpectedProperty(String),
/// When a rule has a required property. The string should be the field name.
MissingProperty(String),
/// When a rule must define at least one property in a given set.
MissingAnyProperty(Vec<String>),
/// When a property is associated with something else than an expected boolean. The string is
/// the property name.
BooleanExpected(String),
/// When a property is associated with something else than an expected string. The string is
/// the property name.
StringExpected(String),
/// When a property is associated with something else than an expected unsigned number. The
/// string is the property name.
UsizeExpected(String),
/// When a property is associated with something else than an expected float. The string is the
/// property name.
FloatExpected(String),
/// When a property is associated with something else than an expected list of strings. The
/// string is the property name.
StringListExpected(String),
/// When a property is associated with something else than an expected require mode. The
/// string is the property name.
RequireModeExpected(String),
/// When the value type is invalid. The string is the property name that was given the wrong
/// value type.
UnexpectedValueType(String),
/// When the value is invalid.
UnexpectedValue { property: String, message: String },
/// When a rule cannot have multiple properties defined at the same time.
PropertyCollision(Vec<String>),
/// When a rule can only be used internally by darklua. The string is the rule name
/// (this error should not surface to external consumers)
InternalUsageOnly(String),
}
fn enumerate_properties(properties: &[String]) -> String {
let last_index = properties.len().saturating_sub(1);
properties
.iter()
.enumerate()
.map(|(i, name)| {
if i == 0 {
format!("`{}`", name)
} else if i == last_index {
format!(" and `{}`", name)
} else {
format!(", `{}`", name)
}
})
.collect()
}
impl fmt::Display for RuleConfigurationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use RuleConfigurationError::*;
match self {
UnexpectedProperty(property) => write!(f, "unexpected field '{}'", property),
MissingProperty(property) => write!(f, "missing required field '{}'", property),
MissingAnyProperty(properties) => write!(
f,
"missing one field from {}",
enumerate_properties(properties)
),
BooleanExpected(property) => {
write!(f, "boolean value expected for field '{}'", property)
}
StringExpected(property) => write!(f, "string value expected for field '{}'", property),
UsizeExpected(property) => {
write!(f, "unsigned integer expected for field '{}'", property)
}
FloatExpected(property) => write!(f, "float value expected for field '{}'", property),
StringListExpected(property) => {
write!(f, "list of string expected for field '{}'", property)
}
RequireModeExpected(property) => {
write!(f, "require mode value expected for field `{}`", property)
}
UnexpectedValueType(property) => write!(f, "unexpected type for field '{}'", property),
UnexpectedValue { property, message } => {
write!(f, "unexpected value for field '{}': {}", property, message)
}
PropertyCollision(properties) => write!(
f,
"the fields {} cannot be defined together",
enumerate_properties(properties)
),
InternalUsageOnly(rule_name) => {
write!(
f,
"usage of rule `{}` is reserved for darklua internal processing",
rule_name
)
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn enumerate_one_property() {
assert_eq!(enumerate_properties(&["prop".to_owned()]), "`prop`")
}
#[test]
fn enumerate_two_properties() {
assert_eq!(
enumerate_properties(&["prop".to_owned(), "prop2".to_owned()]),
"`prop` and `prop2`"
)
}
#[test]
fn enumerate_three_properties() {
assert_eq!(
enumerate_properties(&["prop".to_owned(), "prop2".to_owned(), "prop3".to_owned()]),
"`prop`, `prop2` and `prop3`"
)
}
}