diff --git a/book-example/src/format/config.md b/book-example/src/format/config.md index 0b671557..a76c9d08 100644 --- a/book-example/src/format/config.md +++ b/book-example/src/format/config.md @@ -9,6 +9,8 @@ Here is an example of what a ***book.toml*** file might look like: title = "Example book" author = "John Doe" description = "The example book covers examples." + +[rust] edition = "2018" [build] @@ -44,7 +46,6 @@ This is general information about your book. `src` directly under the root folder. But this is configurable with the `src` key in the configuration file. - **language:** The main language of the book, which is used as a language attribute `` for example. -- **edition**: Rust edition to use by default for the code snippets. Defaults to `rustdoc` defaults (2015). **book.toml** ```toml @@ -54,9 +55,14 @@ authors = ["John Doe", "Jane Doe"] description = "The example book covers examples." src = "my-src" # the source files will be found in `root/my-src` instead of `root/src` language = "en" -edition = "2018" ``` +### Rust options + +Options for the Rust compiler used for playpen. + +- **edition**: Rust edition to use by default for the code snippets. Defaults to `rustdoc` defaults (2015). + ### Build options This controls the build process of your book. diff --git a/src/book/mod.rs b/src/book/mod.rs index 959800ed..57ae2e3f 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -265,7 +265,7 @@ impl MDBook { let mut cmd = Command::new("rustdoc"); cmd.arg(&path).arg("--test").args(&library_args); - if let Some(edition) = self.config.book.edition { + if let Some(edition) = self.config.rust.edition { match edition { RustEdition::E2015 => { cmd.args(&["--edition", "2015"]); diff --git a/src/config.rs b/src/config.rs index 2c4e12d3..b0b09f90 100644 --- a/src/config.rs +++ b/src/config.rs @@ -72,6 +72,8 @@ pub struct Config { pub book: BookConfig, /// Information about the build environment. pub build: BuildConfig, + /// Information passed to the Rust playground + pub rust: RustConfig, rest: Value, } @@ -280,6 +282,7 @@ impl Default for Config { Config { book: BookConfig::default(), build: BuildConfig::default(), + rust: RustConfig::default(), rest: Value::Table(Table::default()), } } @@ -320,9 +323,15 @@ impl<'de> Deserialize<'de> for Config { .and_then(|value| value.try_into().ok()) .unwrap_or_default(); + let rust: RustConfig = table + .remove("rust") + .and_then(|value| value.try_into().ok()) + .unwrap_or_default(); + Ok(Config { book, build, + rust, rest: Value::Table(table), }) } @@ -393,8 +402,6 @@ pub struct BookConfig { pub multilingual: bool, /// The main language of the book. pub language: Option, - /// Rust edition to use for the code. - pub edition: Option, } impl Default for BookConfig { @@ -406,11 +413,42 @@ impl Default for BookConfig { src: PathBuf::from("src"), multilingual: false, language: Some(String::from("en")), - edition: None, } } } +/// Configuration for the build procedure. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(default, rename_all = "kebab-case")] +pub struct BuildConfig { + /// Where to put built artefacts relative to the book's root directory. + pub build_dir: PathBuf, + /// Should non-existent markdown files specified in `SUMMARY.md` be created + /// if they don't exist? + pub create_missing: bool, + /// Should the default preprocessors always be used when they are + /// compatible with the renderer? + pub use_default_preprocessors: bool, +} + +impl Default for BuildConfig { + fn default() -> BuildConfig { + BuildConfig { + build_dir: PathBuf::from("book"), + create_missing: true, + use_default_preprocessors: true, + } + } +} + +/// Configuration for the Rust compiler(e.g., for playpen) +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[serde(default, rename_all = "kebab-case")] +pub struct RustConfig { + /// Rust edition used in playpen + pub edition: Option, +} + #[derive(Debug, Copy, Clone, PartialEq)] /// Rust edition to use for the code. pub enum RustEdition { @@ -451,8 +489,8 @@ impl<'de> Deserialize<'de> for RustEdition { let edition = match edition.as_str() { "2018" => RustEdition::E2018, "2015" => RustEdition::E2015, - _ => { - return Err(D::Error::custom("Unknown Rust edition")); + e => { + return Err(D::Error::custom(format!("Unknown Rust edition: {}", e))); } }; @@ -460,30 +498,6 @@ impl<'de> Deserialize<'de> for RustEdition { } } -/// Configuration for the build procedure. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(default, rename_all = "kebab-case")] -pub struct BuildConfig { - /// Where to put built artefacts relative to the book's root directory. - pub build_dir: PathBuf, - /// Should non-existent markdown files specified in `SUMMARY.md` be created - /// if they don't exist? - pub create_missing: bool, - /// Should the default preprocessors always be used when they are - /// compatible with the renderer? - pub use_default_preprocessors: bool, -} - -impl Default for BuildConfig { - fn default() -> BuildConfig { - BuildConfig { - build_dir: PathBuf::from("book"), - create_missing: true, - use_default_preprocessors: true, - } - } -} - /// Configuration for the HTML renderer. #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(default, rename_all = "kebab-case")] @@ -699,13 +713,13 @@ mod tests { multilingual: true, src: PathBuf::from("source"), language: Some(String::from("ja")), - edition: None, }; let build_should_be = BuildConfig { build_dir: PathBuf::from("outputs"), create_missing: false, use_default_preprocessors: true, }; + let rust_should_be = RustConfig { edition: None }; let playpen_should_be = Playpen { editable: true, copyable: true, @@ -728,6 +742,7 @@ mod tests { assert_eq!(got.book, book_should_be); assert_eq!(got.build, build_should_be); + assert_eq!(got.rust, rust_should_be); assert_eq!(got.html_config().unwrap(), html_should_be); } @@ -739,6 +754,7 @@ mod tests { description = "Create book from markdown files. Like Gitbook but implemented in Rust" authors = ["Mathieu David"] src = "./source" + [rust] edition = "2015" "#; @@ -749,12 +765,17 @@ mod tests { )), authors: vec![String::from("Mathieu David")], src: PathBuf::from("./source"), - edition: Some(RustEdition::E2015), ..Default::default() }; let got = Config::from_str(src).unwrap(); assert_eq!(got.book, book_should_be); + + let rust_should_be = RustConfig { + edition: Some(RustEdition::E2015), + }; + let got = Config::from_str(src).unwrap(); + assert_eq!(got.rust, rust_should_be); } #[test] @@ -765,22 +786,16 @@ mod tests { description = "Create book from markdown files. Like Gitbook but implemented in Rust" authors = ["Mathieu David"] src = "./source" + [rust] edition = "2018" "#; - let book_should_be = BookConfig { - title: Some(String::from("mdBook Documentation")), - description: Some(String::from( - "Create book from markdown files. Like Gitbook but implemented in Rust", - )), - authors: vec![String::from("Mathieu David")], - src: PathBuf::from("./source"), + let rust_should_be = RustConfig { edition: Some(RustEdition::E2018), - ..Default::default() }; let got = Config::from_str(src).unwrap(); - assert_eq!(got.book, book_should_be); + assert_eq!(got.rust, rust_should_be); } #[test] diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 6029f0c9..302ec419 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -349,7 +349,7 @@ impl Renderer for HtmlHandlebars { data: data.clone(), is_index, html_config: html_config.clone(), - edition: ctx.config.book.edition, + edition: ctx.config.rust.edition, }; self.render_item(item, ctx, &mut print_content)?; is_index = false; @@ -365,7 +365,7 @@ impl Renderer for HtmlHandlebars { debug!("Render template"); let rendered = handlebars.render("index", &data)?; - let rendered = self.post_process(rendered, &html_config.playpen, ctx.config.book.edition); + let rendered = self.post_process(rendered, &html_config.playpen, ctx.config.rust.edition); utils::fs::write_file(&destination, "print.html", rendered.as_bytes())?; debug!("Creating print.html ✓");