From 1cc4cbb202583c5261ba56743d7c6d92b24faf54 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 29 Oct 2025 20:29:46 -0700 Subject: [PATCH] Add Config::contains_key This adds the method `contains_key` to assist with detecting if a key is set in the config. There have been a few scenarios where I have needed this when upgrading to 0.5. For now this only supports the `output` and `preprocessor`. Checking the presence in the other tables isn't easy, but could potentially be added if needed. --- crates/mdbook-core/src/config.rs | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/crates/mdbook-core/src/config.rs b/crates/mdbook-core/src/config.rs index 760af9922e..166e921ef3 100644 --- a/crates/mdbook-core/src/config.rs +++ b/crates/mdbook-core/src/config.rs @@ -209,6 +209,23 @@ impl Config { .transpose() } + /// Returns whether the config contains the given dotted key name. + /// + /// The key can have dotted indices to access nested items (e.g. + /// `preprocessor.foo.bar` will check if that key is set in the config). + /// + /// This can only access the `output` and `preprocessor` tables. + pub fn contains_key(&self, name: &str) -> bool { + if let Some(key) = name.strip_prefix("output.") { + self.output.read(key) + } else if let Some(key) = name.strip_prefix("preprocessor.") { + self.preprocessor.read(key) + } else { + panic!("invalid key `{name}`"); + } + .is_some() + } + /// Returns the configuration for all preprocessors. pub fn preprocessors<'de, T: Deserialize<'de>>(&self) -> Result> { self.preprocessor @@ -1161,4 +1178,24 @@ mod tests { "Failed to deserialize `preprocessor.foo.x`" ); } + + #[test] + fn contains_key() { + let src = r#" + [preprocessor.foo] + x = 123 + [output.foo.sub] + y = 'x' + "#; + let cfg = Config::from_str(src).unwrap(); + assert!(cfg.contains_key("preprocessor.foo")); + assert!(cfg.contains_key("preprocessor.foo.x")); + assert!(!cfg.contains_key("preprocessor.bar")); + assert!(!cfg.contains_key("preprocessor.foo.y")); + assert!(cfg.contains_key("output.foo")); + assert!(cfg.contains_key("output.foo.sub")); + assert!(cfg.contains_key("output.foo.sub.y")); + assert!(!cfg.contains_key("output.bar")); + assert!(!cfg.contains_key("output.foo.sub.z")); + } }