From 78b5dfd56f4fe97cfc6727fcb6f1fd02e69482a2 Mon Sep 17 00:00:00 2001 From: JulianGmp Date: Thu, 27 Jun 2024 01:06:01 +0200 Subject: [PATCH] disincentivize usage of functions that expose toml::Table in Config --- examples/nop-preprocessor.rs | 13 +++++++++++-- src/config.rs | 22 ++++++++++++++++++++++ tests/custom_preprocessors.rs | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/examples/nop-preprocessor.rs b/examples/nop-preprocessor.rs index 398d7fc784..e055badb51 100644 --- a/examples/nop-preprocessor.rs +++ b/examples/nop-preprocessor.rs @@ -71,6 +71,7 @@ fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> ! { /// in your main `lib.rs` file. mod nop_lib { use super::*; + use serde::Deserialize; /// A no-op preprocessor. pub struct Nop; @@ -87,10 +88,18 @@ mod nop_lib { } fn run(&self, ctx: &PreprocessorContext, book: Book) -> Result { + // The config options our preprocessor uses, deserialized from the book.toml that + // mdbook uses + #[derive(Deserialize)] + struct Config { + blow_up: bool, + } + // In testing we want to tell the preprocessor to blow up by setting a // particular config value - if let Some(nop_cfg) = ctx.config.get_preprocessor(self.name()) { - if nop_cfg.contains_key("blow-up") { + let nop_cfg: Option = ctx.config.get_preprocessor_deserialized(self.name())?; + if let Some(nop_cfg) = nop_cfg { + if nop_cfg.blow_up { anyhow::bail!("Boom!!1!"); } } diff --git a/src/config.rs b/src/config.rs index 1438be29a3..77b4e57e95 100644 --- a/src/config.rs +++ b/src/config.rs @@ -240,17 +240,39 @@ impl Config { } /// Get the table associated with a particular renderer. + #[deprecated = "prefer get_renderer_deserialized over get_renderer"] pub fn get_renderer>(&self, index: I) -> Option<&Table> { let key = format!("output.{}", index.as_ref()); self.get(&key).and_then(Value::as_table) } + /// Convenience function to fetch the renderer section from the config and deserialize it + /// into some arbitrary type. + pub fn get_renderer_deserialized<'de, T: Deserialize<'de>, I: AsRef>( + &self, + index: I, + ) -> Result> { + let key = format!("output.{}", index.as_ref()); + self.get_deserialized_opt(key) + } + /// Get the table associated with a particular preprocessor. + #[deprecated = "prefer get_preprocessor_deserialized over get_preprocessor"] pub fn get_preprocessor>(&self, index: I) -> Option<&Table> { let key = format!("preprocessor.{}", index.as_ref()); self.get(&key).and_then(Value::as_table) } + /// Convenience function to fetch the preprocessor section from the config and deserialize it + /// into some arbitrary type. + pub fn get_preprocessor_deserialized<'de, T: Deserialize<'de>, I: AsRef>( + &self, + index: I, + ) -> Result> { + let key = format!("preprocessor.{}", index.as_ref()); + self.get_deserialized_opt(key) + } + fn from_legacy(mut table: Value) -> Config { let mut cfg = Config::default(); diff --git a/tests/custom_preprocessors.rs b/tests/custom_preprocessors.rs index 8237602de0..c1d47d8956 100644 --- a/tests/custom_preprocessors.rs +++ b/tests/custom_preprocessors.rs @@ -37,7 +37,7 @@ fn ask_the_preprocessor_to_blow_up() { md.with_preprocessor(example()); md.config - .set("preprocessor.nop-preprocessor.blow-up", true) + .set("preprocessor.nop-preprocessor.blow_up", true) .unwrap(); let got = md.build();