Skip to content

Commit 43fb1b6

Browse files
authored
Merge pull request #651 from MartinHowarthFlexciton/allow-bool-hash-and-dont-panic
Allow bool hash and dont panic
2 parents 9f2d37e + 1fafe75 commit 43fb1b6

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

src/file/format/yaml.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ fn from_yaml_value(
5050
match key {
5151
yaml::Yaml::String(k) => m.insert(k.to_owned(), from_yaml_value(uri, value)?),
5252
yaml::Yaml::Integer(k) => m.insert(k.to_string(), from_yaml_value(uri, value)?),
53-
_ => unreachable!(),
53+
yaml::Yaml::Boolean(k) => m.insert(k.to_string(), from_yaml_value(uri, value)?),
54+
other => Err(Box::new(UnsupportedHashKeyError(format!("{other:?}"))))?,
5455
};
5556
}
5657
Ok(Value::new(uri, ValueKind::Table(m)))
@@ -103,3 +104,22 @@ impl Error for FloatParsingError {
103104
"Floating point number parsing failed"
104105
}
105106
}
107+
108+
#[derive(Debug, Clone)]
109+
struct UnsupportedHashKeyError(String);
110+
111+
impl fmt::Display for UnsupportedHashKeyError {
112+
fn fmt(&self, format: &mut fmt::Formatter<'_>) -> fmt::Result {
113+
write!(
114+
format,
115+
"Cannot parse {} because it is an unsupported hash key type",
116+
self.0
117+
)
118+
}
119+
}
120+
121+
impl Error for UnsupportedHashKeyError {
122+
fn description(&self) -> &str {
123+
"Unsupported yaml hash key found"
124+
}
125+
}

tests/testsuite/file_yaml.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,47 @@ fn yaml() {
338338
let date: DateTime<Utc> = s.get("yaml_datetime").unwrap();
339339
assert_eq!(date, Utc.with_ymd_and_hms(2017, 6, 12, 10, 58, 30).unwrap());
340340
}
341+
342+
#[test]
343+
/// We only support certain types as keys to a yaml hash, this test ensures
344+
/// we communicate that to the user effectively.
345+
fn test_yaml_parsing_unsupported_hash_has_useful_error_message() {
346+
let result = Config::builder()
347+
.add_source(File::from_str(
348+
r#"
349+
inner_vec:
350+
[1, 2]: "unsupported"
351+
"#,
352+
FileFormat::Yaml,
353+
))
354+
.build();
355+
assert!(result.is_err());
356+
assert_data_eq!(
357+
result.unwrap_err().to_string(),
358+
str!["Cannot parse Array([Integer(1), Integer(2)]) because it is an unsupported hash key type"]
359+
);
360+
}
361+
362+
#[test]
363+
fn test_yaml_parsing_bool_hash() {
364+
#[derive(Debug, Deserialize)]
365+
struct TestStruct {
366+
inner_bool: HashMap<bool, String>,
367+
}
368+
369+
let config = Config::builder()
370+
.add_source(File::from_str(
371+
r#"
372+
inner_bool:
373+
true: "bool true"
374+
false: "bool false"
375+
"#,
376+
FileFormat::Yaml,
377+
))
378+
.build()
379+
.unwrap()
380+
.try_deserialize::<TestStruct>()
381+
.unwrap();
382+
assert_eq!(config.inner_bool.get(&true).unwrap(), "bool true");
383+
assert_eq!(config.inner_bool.get(&false).unwrap(), "bool false");
384+
}

0 commit comments

Comments
 (0)