@@ -209,6 +209,23 @@ impl Config {
209209 . transpose ( )
210210 }
211211
212+ /// Returns whether the config contains the given dotted key name.
213+ ///
214+ /// The key can have dotted indices to access nested items (e.g.
215+ /// `preprocessor.foo.bar` will check if that key is set in the config).
216+ ///
217+ /// This can only access the `output` and `preprocessor` tables.
218+ pub fn contains_key ( & self , name : & str ) -> bool {
219+ if let Some ( key) = name. strip_prefix ( "output." ) {
220+ self . output . read ( key)
221+ } else if let Some ( key) = name. strip_prefix ( "preprocessor." ) {
222+ self . preprocessor . read ( key)
223+ } else {
224+ panic ! ( "invalid key `{name}`" ) ;
225+ }
226+ . is_some ( )
227+ }
228+
212229 /// Returns the configuration for all preprocessors.
213230 pub fn preprocessors < ' de , T : Deserialize < ' de > > ( & self ) -> Result < BTreeMap < String , T > > {
214231 self . preprocessor
@@ -1161,4 +1178,24 @@ mod tests {
11611178 "Failed to deserialize `preprocessor.foo.x`"
11621179 ) ;
11631180 }
1181+
1182+ #[ test]
1183+ fn contains_key ( ) {
1184+ let src = r#"
1185+ [preprocessor.foo]
1186+ x = 123
1187+ [output.foo.sub]
1188+ y = 'x'
1189+ "# ;
1190+ let cfg = Config :: from_str ( src) . unwrap ( ) ;
1191+ assert ! ( cfg. contains_key( "preprocessor.foo" ) ) ;
1192+ assert ! ( cfg. contains_key( "preprocessor.foo.x" ) ) ;
1193+ assert ! ( !cfg. contains_key( "preprocessor.bar" ) ) ;
1194+ assert ! ( !cfg. contains_key( "preprocessor.foo.y" ) ) ;
1195+ assert ! ( cfg. contains_key( "output.foo" ) ) ;
1196+ assert ! ( cfg. contains_key( "output.foo.sub" ) ) ;
1197+ assert ! ( cfg. contains_key( "output.foo.sub.y" ) ) ;
1198+ assert ! ( !cfg. contains_key( "output.bar" ) ) ;
1199+ assert ! ( !cfg. contains_key( "output.foo.sub.z" ) ) ;
1200+ }
11641201}
0 commit comments