brewery
notashelf /
27a509362bd3f800fbfa11967e2408002079a941

beer

public

A terminal worth pouring time into

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/beer.git

Commit 27a509362bd3

tarball

NotAShelf <raf@notashelf.dev> · 2026-06-26 07:43 UTC

unverified3 files changed+57-11
config: warn on unknown keys instead of dropping them silently

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id06a7e2c96cfdcb69a21fa0416d988696a6a6964
diff --git a/Cargo.lock b/Cargo.lockindex 2d80f2f..09449ee 100644--- a/Cargo.lock+++ b/Cargo.lock@@ -42,6 +42,7 @@ dependencies = [  "pound",  "rustix",  "serde",+ "serde_ignored",  "smithay-client-toolkit",  "thiserror",  "toml",@@ -489,6 +490,16 @@ dependencies = [ ]  [[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" source = "registry+https://github.com/rust-lang/crates.io-index"diff --git a/Cargo.toml b/Cargo.tomlindex e7201d8..9208dff 100644--- a/Cargo.toml+++ b/Cargo.toml@@ -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"diff --git a/src/config.rs b/src/config.rsindex 4f335ee..fcdcccb 100644--- a/src/config.rs+++ b/src/config.rs@@ -195,19 +195,32 @@ impl Config {         if !path.exists() {             return Self::default();         }-        match std::fs::read_to_string(&path) {-            Ok(text) => match toml::from_str(&text) {-                Ok(config) => {-                    tracing::info!("loaded config from {}", path.display());-                    config-                }-                Err(err) => {-                    tracing::warn!("config {}: {err}; using defaults", path.display());-                    Self::default()-                }-            },+        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+            }+            Err(err) => {+                tracing::warn!("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");+    } }