Add support for Rust edition
This commit is contained in:
parent
bd0f434225
commit
d39d4517aa
|
@ -3,6 +3,7 @@ title = "mdBook Documentation"
|
||||||
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
||||||
authors = ["Mathieu David", "Michael-F-Bryan"]
|
authors = ["Mathieu David", "Michael-F-Bryan"]
|
||||||
language = "en"
|
language = "en"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[output.html]
|
[output.html]
|
||||||
mathjax-support = true
|
mathjax-support = true
|
||||||
|
|
|
@ -9,6 +9,7 @@ Here is an example of what a ***book.toml*** file might look like:
|
||||||
title = "Example book"
|
title = "Example book"
|
||||||
author = "John Doe"
|
author = "John Doe"
|
||||||
description = "The example book covers examples."
|
description = "The example book covers examples."
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
build-dir = "my-example-book"
|
build-dir = "my-example-book"
|
||||||
|
@ -43,6 +44,7 @@ This is general information about your book.
|
||||||
`src` directly under the root folder. But this is configurable with the `src`
|
`src` directly under the root folder. But this is configurable with the `src`
|
||||||
key in the configuration file.
|
key in the configuration file.
|
||||||
- **language:** The main language of the book, which is used as a language attribute `<html lang="en">` for example.
|
- **language:** The main language of the book, which is used as a language attribute `<html lang="en">` for example.
|
||||||
|
- **edition**: Rust edition to use by default for the code snippets. Defaults to `rustdoc` defaults (2015).
|
||||||
|
|
||||||
**book.toml**
|
**book.toml**
|
||||||
```toml
|
```toml
|
||||||
|
@ -52,6 +54,7 @@ authors = ["John Doe", "Jane Doe"]
|
||||||
description = "The example book covers examples."
|
description = "The example book covers examples."
|
||||||
src = "my-src" # the source files will be found in `root/my-src` instead of `root/src`
|
src = "my-src" # the source files will be found in `root/my-src` instead of `root/src`
|
||||||
language = "en"
|
language = "en"
|
||||||
|
edition = "2018"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build options
|
### Build options
|
||||||
|
|
|
@ -27,7 +27,7 @@ use crate::preprocess::{
|
||||||
use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer};
|
use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer};
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::{Config, RustEdition};
|
||||||
|
|
||||||
/// The object used to manage and build a book.
|
/// The object used to manage and build a book.
|
||||||
pub struct MDBook {
|
pub struct MDBook {
|
||||||
|
@ -262,11 +262,21 @@ impl MDBook {
|
||||||
let mut tmpf = utils::fs::create_file(&path)?;
|
let mut tmpf = utils::fs::create_file(&path)?;
|
||||||
tmpf.write_all(ch.content.as_bytes())?;
|
tmpf.write_all(ch.content.as_bytes())?;
|
||||||
|
|
||||||
let output = Command::new("rustdoc")
|
let mut cmd = Command::new("rustdoc");
|
||||||
.arg(&path)
|
cmd.arg(&path).arg("--test").args(&library_args);
|
||||||
.arg("--test")
|
|
||||||
.args(&library_args)
|
if let Some(edition) = self.config.book.edition {
|
||||||
.output()?;
|
match edition {
|
||||||
|
RustEdition::E2015 => {
|
||||||
|
cmd.args(&["--edition", "2015"]);
|
||||||
|
}
|
||||||
|
RustEdition::E2018 => {
|
||||||
|
cmd.args(&["--edition", "2018"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = cmd.output()?;
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
bail!(ErrorKind::Subprocess(
|
bail!(ErrorKind::Subprocess(
|
||||||
|
|
105
src/config.rs
105
src/config.rs
|
@ -393,6 +393,8 @@ pub struct BookConfig {
|
||||||
pub multilingual: bool,
|
pub multilingual: bool,
|
||||||
/// The main language of the book.
|
/// The main language of the book.
|
||||||
pub language: Option<String>,
|
pub language: Option<String>,
|
||||||
|
/// Rust edition to use for the code.
|
||||||
|
pub edition: Option<RustEdition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BookConfig {
|
impl Default for BookConfig {
|
||||||
|
@ -404,10 +406,60 @@ impl Default for BookConfig {
|
||||||
src: PathBuf::from("src"),
|
src: PathBuf::from("src"),
|
||||||
multilingual: false,
|
multilingual: false,
|
||||||
language: Some(String::from("en")),
|
language: Some(String::from("en")),
|
||||||
|
edition: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
/// Rust edition to use for the code.
|
||||||
|
pub enum RustEdition {
|
||||||
|
/// The 2018 edition of Rust
|
||||||
|
E2018,
|
||||||
|
/// The 2015 edition of Rust
|
||||||
|
E2015,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for RustEdition {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
RustEdition::E2015 => serializer.serialize_str("2015"),
|
||||||
|
RustEdition::E2018 => serializer.serialize_str("2018"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for RustEdition {
|
||||||
|
fn deserialize<D>(de: D) -> std::result::Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
use serde::de::Error;
|
||||||
|
|
||||||
|
let raw = Value::deserialize(de)?;
|
||||||
|
|
||||||
|
let edition = match raw {
|
||||||
|
Value::String(s) => s,
|
||||||
|
_ => {
|
||||||
|
return Err(D::Error::custom("Rust edition should be a string"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let edition = match edition.as_str() {
|
||||||
|
"2018" => RustEdition::E2018,
|
||||||
|
"2015" => RustEdition::E2015,
|
||||||
|
_ => {
|
||||||
|
return Err(D::Error::custom("Unknown Rust edition"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(edition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Configuration for the build procedure.
|
/// Configuration for the build procedure.
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(default, rename_all = "kebab-case")]
|
#[serde(default, rename_all = "kebab-case")]
|
||||||
|
@ -647,6 +699,7 @@ mod tests {
|
||||||
multilingual: true,
|
multilingual: true,
|
||||||
src: PathBuf::from("source"),
|
src: PathBuf::from("source"),
|
||||||
language: Some(String::from("ja")),
|
language: Some(String::from("ja")),
|
||||||
|
edition: None,
|
||||||
};
|
};
|
||||||
let build_should_be = BuildConfig {
|
let build_should_be = BuildConfig {
|
||||||
build_dir: PathBuf::from("outputs"),
|
build_dir: PathBuf::from("outputs"),
|
||||||
|
@ -678,6 +731,58 @@ mod tests {
|
||||||
assert_eq!(got.html_config().unwrap(), html_should_be);
|
assert_eq!(got.html_config().unwrap(), html_should_be);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn edition_2015() {
|
||||||
|
let src = r#"
|
||||||
|
[book]
|
||||||
|
title = "mdBook Documentation"
|
||||||
|
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
||||||
|
authors = ["Mathieu David"]
|
||||||
|
src = "./source"
|
||||||
|
edition = "2015"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
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"),
|
||||||
|
edition: Some(RustEdition::E2015),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let got = Config::from_str(src).unwrap();
|
||||||
|
assert_eq!(got.book, book_should_be);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn edition_2018() {
|
||||||
|
let src = r#"
|
||||||
|
[book]
|
||||||
|
title = "mdBook Documentation"
|
||||||
|
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
||||||
|
authors = ["Mathieu David"]
|
||||||
|
src = "./source"
|
||||||
|
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"),
|
||||||
|
edition: Some(RustEdition::E2018),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let got = Config::from_str(src).unwrap();
|
||||||
|
assert_eq!(got.book, book_should_be);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn load_arbitrary_output_type() {
|
fn load_arbitrary_output_type() {
|
||||||
#[derive(Debug, Deserialize, PartialEq)]
|
#[derive(Debug, Deserialize, PartialEq)]
|
||||||
|
|
Loading…
Reference in New Issue