forked from NotAShelf/beer
config: warn on unknown keys instead of dropping them silently
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id06a7e2c96cfdcb69a21fa0416d988696a6a6964
This commit is contained in:
parent
5a9242b53f
commit
27a509362b
3 changed files with 57 additions and 11 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -42,6 +42,7 @@ dependencies = [
|
|||
"pound",
|
||||
"rustix",
|
||||
"serde",
|
||||
"serde_ignored",
|
||||
"smithay-client-toolkit",
|
||||
"thiserror",
|
||||
"toml",
|
||||
|
|
@ -488,6 +489,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_ignored"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.1.1"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ rustix = { version = "1.1.4", features = [
|
|||
"fs",
|
||||
] }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_ignored = "0.1.12"
|
||||
smithay-client-toolkit = "0.20.0"
|
||||
thiserror = "2.0.18"
|
||||
toml = "0.9"
|
||||
|
|
|
|||
|
|
@ -195,8 +195,26 @@ impl Config {
|
|||
if !path.exists() {
|
||||
return Self::default();
|
||||
}
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(text) => match toml::from_str(&text) {
|
||||
let text = match std::fs::read_to_string(&path) {
|
||||
Ok(text) => text,
|
||||
Err(err) => {
|
||||
tracing::warn!("read config {}: {err}; using defaults", path.display());
|
||||
return Self::default();
|
||||
}
|
||||
};
|
||||
// Deserialize through serde_ignored so a typo'd key (`font-sze`) is
|
||||
// reported instead of silently dropped, while still loading: unknown
|
||||
// keys stay tolerated, keeping forward-compatibility with newer configs.
|
||||
let de = match toml::Deserializer::parse(&text) {
|
||||
Ok(de) => de,
|
||||
Err(err) => {
|
||||
tracing::warn!("config {}: {err}; using defaults", path.display());
|
||||
return Self::default();
|
||||
}
|
||||
};
|
||||
match serde_ignored::deserialize(de, |key| {
|
||||
tracing::warn!("config {}: unknown key `{key}` ignored", path.display());
|
||||
}) {
|
||||
Ok(config) => {
|
||||
tracing::info!("loaded config from {}", path.display());
|
||||
config
|
||||
|
|
@ -205,11 +223,6 @@ impl Config {
|
|||
tracing::warn!("config {}: {err}; using defaults", path.display());
|
||||
Self::default()
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::warn!("read config {}: {err}; using defaults", path.display());
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -253,4 +266,25 @@ mod tests {
|
|||
assert_eq!(c.main.term, "beer");
|
||||
assert_eq!(c.scrollback.lines, 10_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unknown_keys_are_reported_but_still_load() {
|
||||
let toml = r##"
|
||||
[main]
|
||||
font-sze = 14
|
||||
font = "JetBrains Mono"
|
||||
|
||||
[made-up]
|
||||
x = 1
|
||||
"##;
|
||||
let mut unknown = Vec::new();
|
||||
let de = toml::Deserializer::parse(toml).unwrap();
|
||||
let c: Config =
|
||||
serde_ignored::deserialize(de, |key| unknown.push(key.to_string())).unwrap();
|
||||
// The typo and the bogus table are both surfaced...
|
||||
assert!(unknown.iter().any(|k| k == "main.font-sze"), "{unknown:?}");
|
||||
assert!(unknown.iter().any(|k| k == "made-up"), "{unknown:?}");
|
||||
// ...yet the valid key still loaded.
|
||||
assert_eq!(c.main.font, "JetBrains Mono");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue