Switch all public types to non_exhaustive
This switches all public types to use non_exhaustive to make it easier to make additions without a semver-breaking change. Some of the ergonomics are hampered due to the lack of exhaustiveness checking. Hopefully some day in the future, non_exhaustive_omitted_patterns_lint or something like it will get stabilized. Closes https://github.com/rust-lang/mdBook/issues/1835
This commit is contained in:
parent
c25e866796
commit
5956092b4b
18 changed files with 90 additions and 122 deletions
|
|
@ -9,6 +9,9 @@ members = [
|
|||
all = { level = "allow", priority = -2 }
|
||||
correctness = { level = "warn", priority = -1 }
|
||||
complexity = { level = "warn", priority = -1 }
|
||||
exhaustive_enums = "warn"
|
||||
exhaustive_structs = "warn"
|
||||
manual_non_exhaustive = "warn"
|
||||
|
||||
[workspace.lints.rust]
|
||||
missing_docs = "warn"
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ use std::path::PathBuf;
|
|||
/// [`iter()`]: #method.iter
|
||||
/// [`for_each_mut()`]: #method.for_each_mut
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Book {
|
||||
/// The sections in this book.
|
||||
pub sections: Vec<BookItem>,
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
|
||||
impl Book {
|
||||
|
|
@ -30,10 +30,7 @@ impl Book {
|
|||
|
||||
/// Creates a new book with the given items.
|
||||
pub fn new_with_items(items: Vec<BookItem>) -> Book {
|
||||
Book {
|
||||
sections: items,
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
Book { sections: items }
|
||||
}
|
||||
|
||||
/// Get a depth-first iterator over the items in the book.
|
||||
|
|
@ -81,6 +78,7 @@ where
|
|||
|
||||
/// Enum representing any type of item which can be added to a book.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub enum BookItem {
|
||||
/// A nested chapter.
|
||||
Chapter(Chapter),
|
||||
|
|
@ -99,6 +97,7 @@ impl From<Chapter> for BookItem {
|
|||
/// The representation of a "chapter", usually mapping to a single file on
|
||||
/// disk however it may contain multiple sub-chapters.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Chapter {
|
||||
/// The chapter's name.
|
||||
pub name: String,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ use toml::value::Table;
|
|||
/// The overall configuration object for MDBook, essentially an in-memory
|
||||
/// representation of `book.toml`.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub struct Config {
|
||||
/// Metadata about the book.
|
||||
pub book: BookConfig,
|
||||
|
|
@ -386,6 +387,7 @@ fn is_legacy_format(table: &Value) -> bool {
|
|||
/// loading it from disk.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct BookConfig {
|
||||
/// The book's title.
|
||||
pub title: Option<String>,
|
||||
|
|
@ -429,6 +431,7 @@ impl BookConfig {
|
|||
|
||||
/// Text direction to use for HTML output
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub enum TextDirection {
|
||||
/// Left to right.
|
||||
#[serde(rename = "ltr")]
|
||||
|
|
@ -454,6 +457,7 @@ impl TextDirection {
|
|||
/// Configuration for the build procedure.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct BuildConfig {
|
||||
/// Where to put built artefacts relative to the book's root directory.
|
||||
pub build_dir: PathBuf,
|
||||
|
|
@ -481,13 +485,15 @@ impl Default for BuildConfig {
|
|||
/// Configuration for the Rust compiler(e.g., for playground)
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct RustConfig {
|
||||
/// Rust edition used in playground
|
||||
pub edition: Option<RustEdition>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
/// Rust edition to use for the code.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub enum RustEdition {
|
||||
/// The 2024 edition of Rust
|
||||
#[serde(rename = "2024")]
|
||||
|
|
@ -506,6 +512,7 @@ pub enum RustEdition {
|
|||
/// Configuration for the HTML renderer.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct HtmlConfig {
|
||||
/// The theme directory, if specified.
|
||||
pub theme: Option<PathBuf>,
|
||||
|
|
@ -625,6 +632,7 @@ impl HtmlConfig {
|
|||
/// Configuration for how to render the print icon, print.html, and print.css.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct Print {
|
||||
/// Whether print support is enabled.
|
||||
pub enable: bool,
|
||||
|
|
@ -644,6 +652,7 @@ impl Default for Print {
|
|||
/// Configuration for how to fold chapters of sidebar.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct Fold {
|
||||
/// When off, all folds are open. Default: `false`.
|
||||
pub enable: bool,
|
||||
|
|
@ -656,6 +665,7 @@ pub struct Fold {
|
|||
/// Configuration for tweaking how the HTML renderer handles the playground.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct Playground {
|
||||
/// Should playground snippets be editable? Default: `false`.
|
||||
pub editable: bool,
|
||||
|
|
@ -685,6 +695,7 @@ impl Default for Playground {
|
|||
/// Configuration for tweaking how the HTML renderer handles code blocks.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct Code {
|
||||
/// A prefix string to hide lines per language (one or more chars).
|
||||
pub hidelines: HashMap<String, String>,
|
||||
|
|
@ -693,6 +704,7 @@ pub struct Code {
|
|||
/// Configuration of the search functionality of the HTML renderer.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct Search {
|
||||
/// Enable the search feature. Default: `true`.
|
||||
pub enable: bool,
|
||||
|
|
@ -750,6 +762,7 @@ impl Default for Search {
|
|||
/// Search options for chapters (or paths).
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[serde(default, rename_all = "kebab-case")]
|
||||
#[non_exhaustive]
|
||||
pub struct SearchChapterSettings {
|
||||
/// Whether or not indexing is enabled, default `true`.
|
||||
pub enable: Option<bool>,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use std::{path::Path, sync::LazyLock};
|
|||
/// A preprocessor for converting file name `README.md` to `index.md` since
|
||||
/// `README.md` is the de facto index file in markdown-based documentation.
|
||||
#[derive(Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct IndexPreprocessor;
|
||||
|
||||
impl IndexPreprocessor {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const MAX_LINK_NESTED_DEPTH: usize = 10;
|
|||
/// - `{{# playground}}` - Insert runnable Rust files
|
||||
/// - `{{# title}}` - Override \<title\> of a webpage.
|
||||
#[derive(Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct LinkPreprocessor;
|
||||
|
||||
impl LinkPreprocessor {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ use mdbook_core::utils;
|
|||
use mdbook_renderer::{RenderContext, Renderer};
|
||||
use std::fs;
|
||||
|
||||
#[derive(Default)]
|
||||
/// A renderer to output the Markdown after the preprocessors have run. Mostly useful
|
||||
/// when debugging preprocessors.
|
||||
#[derive(Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct MarkdownRenderer;
|
||||
|
||||
impl MarkdownRenderer {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ fn load_summary_item<P: AsRef<Path> + Clone>(
|
|||
SummaryItem::Separator => Ok(BookItem::Separator),
|
||||
SummaryItem::Link(link) => load_chapter(link, src_dir, parent_names).map(BookItem::Chapter),
|
||||
SummaryItem::PartTitle(title) => Ok(BookItem::PartTitle(title.clone())),
|
||||
_ => panic!("SummaryItem {item:?} not covered"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -252,28 +253,21 @@ And here is some \
|
|||
fn load_recursive_link_with_separators() {
|
||||
let (root, temp) = nested_links();
|
||||
|
||||
let nested = Chapter {
|
||||
name: String::from("Nested Chapter 1"),
|
||||
content: String::from("Hello World!"),
|
||||
number: Some(SectionNumber::new([1, 2])),
|
||||
path: Some(PathBuf::from("second.md")),
|
||||
source_path: Some(PathBuf::from("second.md")),
|
||||
parent_names: vec![String::from("Chapter 1")],
|
||||
sub_items: Vec::new(),
|
||||
};
|
||||
let should_be = BookItem::Chapter(Chapter {
|
||||
name: String::from("Chapter 1"),
|
||||
content: String::from(DUMMY_SRC),
|
||||
number: None,
|
||||
path: Some(PathBuf::from("chapter_1.md")),
|
||||
source_path: Some(PathBuf::from("chapter_1.md")),
|
||||
parent_names: Vec::new(),
|
||||
sub_items: vec![
|
||||
let mut nested = Chapter::new(
|
||||
"Nested Chapter 1",
|
||||
String::from("Hello World!"),
|
||||
"second.md",
|
||||
vec![String::from("Chapter 1")],
|
||||
);
|
||||
nested.number = Some(SectionNumber::new([1, 2]));
|
||||
let mut chapter =
|
||||
Chapter::new("Chapter 1", String::from(DUMMY_SRC), "chapter_1.md", vec![]);
|
||||
chapter.sub_items = vec![
|
||||
BookItem::Chapter(nested.clone()),
|
||||
BookItem::Separator,
|
||||
BookItem::Chapter(nested),
|
||||
],
|
||||
});
|
||||
];
|
||||
let should_be = BookItem::Chapter(chapter);
|
||||
|
||||
let got = load_summary_item(&SummaryItem::Link(root), temp.path(), Vec::new()).unwrap();
|
||||
assert_eq!(got, should_be);
|
||||
|
|
@ -282,17 +276,15 @@ And here is some \
|
|||
#[test]
|
||||
fn load_a_book_with_a_single_chapter() {
|
||||
let (link, temp) = dummy_link();
|
||||
let summary = Summary {
|
||||
numbered_chapters: vec![SummaryItem::Link(link)],
|
||||
..Default::default()
|
||||
};
|
||||
let sections = vec![BookItem::Chapter(Chapter {
|
||||
name: String::from("Chapter 1"),
|
||||
content: String::from(DUMMY_SRC),
|
||||
path: Some(PathBuf::from("chapter_1.md")),
|
||||
source_path: Some(PathBuf::from("chapter_1.md")),
|
||||
..Default::default()
|
||||
})];
|
||||
let mut summary = Summary::default();
|
||||
summary.numbered_chapters = vec![SummaryItem::Link(link)];
|
||||
let chapter = Chapter::new(
|
||||
"Chapter 1",
|
||||
String::from(DUMMY_SRC),
|
||||
PathBuf::from("chapter_1.md"),
|
||||
vec![],
|
||||
);
|
||||
let sections = vec![BookItem::Chapter(chapter)];
|
||||
let should_be = Book::new_with_items(sections);
|
||||
|
||||
let got = load_book_from_disk(&summary, temp.path()).unwrap();
|
||||
|
|
@ -303,16 +295,9 @@ And here is some \
|
|||
#[test]
|
||||
fn cant_load_chapters_with_an_empty_path() {
|
||||
let (_, temp) = dummy_link();
|
||||
let summary = Summary {
|
||||
numbered_chapters: vec![SummaryItem::Link(Link {
|
||||
name: String::from("Empty"),
|
||||
location: Some(PathBuf::from("")),
|
||||
..Default::default()
|
||||
})],
|
||||
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut summary = Summary::default();
|
||||
let link = Link::new("Empty", "");
|
||||
summary.numbered_chapters = vec![SummaryItem::Link(link)];
|
||||
let got = load_book_from_disk(&summary, temp.path());
|
||||
assert!(got.is_err());
|
||||
}
|
||||
|
|
@ -323,14 +308,9 @@ And here is some \
|
|||
let dir = temp.path().join("nested");
|
||||
fs::create_dir(&dir).unwrap();
|
||||
|
||||
let summary = Summary {
|
||||
numbered_chapters: vec![SummaryItem::Link(Link {
|
||||
name: String::from("nested"),
|
||||
location: Some(dir),
|
||||
..Default::default()
|
||||
})],
|
||||
..Default::default()
|
||||
};
|
||||
let mut summary = Summary::default();
|
||||
let link = Link::new("nested", dir);
|
||||
summary.numbered_chapters = vec![SummaryItem::Link(link)];
|
||||
|
||||
let got = load_book_from_disk(&summary, temp.path());
|
||||
assert!(got.is_err());
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ impl MDBook {
|
|||
/// BookItem::Chapter(ref chapter) => {},
|
||||
/// BookItem::Separator => {},
|
||||
/// BookItem::PartTitle(ref title) => {}
|
||||
/// _ => {}
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
|
@ -329,6 +330,7 @@ impl MDBook {
|
|||
RustEdition::E2024 => {
|
||||
cmd.args(["--edition", "2024"]);
|
||||
}
|
||||
_ => panic!("RustEdition {edition:?} not covered"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ fn config_respects_preprocessor_selection() {
|
|||
|
||||
let cfg = Config::from_str(cfg_str).unwrap();
|
||||
|
||||
let html_renderer = HtmlHandlebars;
|
||||
let html_renderer = HtmlHandlebars::default();
|
||||
let pre = LinkPreprocessor::new();
|
||||
|
||||
let should_run = preprocessor_should_run(&pre, &html_renderer, &cfg).unwrap();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use std::sync::LazyLock;
|
|||
|
||||
/// The HTML renderer for mdBook.
|
||||
#[derive(Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct HtmlHandlebars;
|
||||
|
||||
impl HtmlHandlebars {
|
||||
|
|
@ -656,6 +657,7 @@ fn make_data(
|
|||
BookItem::Separator => {
|
||||
chapter.insert("spacer".to_owned(), json!("_spacer_"));
|
||||
}
|
||||
_ => panic!("BookItem {item:?} not covered"),
|
||||
}
|
||||
|
||||
chapters.push(chapter);
|
||||
|
|
@ -778,6 +780,7 @@ fn add_playground_pre(
|
|||
Some(RustEdition::E2018) => " edition2018",
|
||||
Some(RustEdition::E2021) => " edition2021",
|
||||
Some(RustEdition::E2024) => " edition2024",
|
||||
Some(_) => panic!("edition {edition:?} not covered"),
|
||||
None => "",
|
||||
}
|
||||
};
|
||||
|
|
@ -1085,14 +1088,9 @@ mod tests {
|
|||
),
|
||||
];
|
||||
for (src, should_be) in &inputs {
|
||||
let got = add_playground_pre(
|
||||
src,
|
||||
&Playground {
|
||||
editable: true,
|
||||
..Playground::default()
|
||||
},
|
||||
None,
|
||||
);
|
||||
let mut p = Playground::default();
|
||||
p.editable = true;
|
||||
let got = add_playground_pre(src, &p, None);
|
||||
assert_eq!(&*got, *should_be);
|
||||
}
|
||||
}
|
||||
|
|
@ -1117,14 +1115,9 @@ mod tests {
|
|||
),
|
||||
];
|
||||
for (src, should_be) in &inputs {
|
||||
let got = add_playground_pre(
|
||||
src,
|
||||
&Playground {
|
||||
editable: true,
|
||||
..Playground::default()
|
||||
},
|
||||
Some(RustEdition::E2015),
|
||||
);
|
||||
let mut p = Playground::default();
|
||||
p.editable = true;
|
||||
let got = add_playground_pre(src, &p, Some(RustEdition::E2015));
|
||||
assert_eq!(&*got, *should_be);
|
||||
}
|
||||
}
|
||||
|
|
@ -1149,14 +1142,9 @@ mod tests {
|
|||
),
|
||||
];
|
||||
for (src, should_be) in &inputs {
|
||||
let got = add_playground_pre(
|
||||
src,
|
||||
&Playground {
|
||||
editable: true,
|
||||
..Playground::default()
|
||||
},
|
||||
Some(RustEdition::E2018),
|
||||
);
|
||||
let mut p = Playground::default();
|
||||
p.editable = true;
|
||||
let got = add_playground_pre(src, &p, Some(RustEdition::E2018));
|
||||
assert_eq!(&*got, *should_be);
|
||||
}
|
||||
}
|
||||
|
|
@ -1181,14 +1169,9 @@ mod tests {
|
|||
),
|
||||
];
|
||||
for (src, should_be) in &inputs {
|
||||
let got = add_playground_pre(
|
||||
src,
|
||||
&Playground {
|
||||
editable: true,
|
||||
..Playground::default()
|
||||
},
|
||||
Some(RustEdition::E2021),
|
||||
);
|
||||
let mut p = Playground::default();
|
||||
p.editable = true;
|
||||
let got = add_playground_pre(src, &p, Some(RustEdition::E2021));
|
||||
assert_eq!(&*got, *should_be);
|
||||
}
|
||||
}
|
||||
|
|
@ -1248,17 +1231,10 @@ mod tests {
|
|||
"<code class=\"language-python hidelines=!!!\"><span class=\"boring\">hidden()\n</span>nothidden():\n<span class=\"boring\"> hidden()\n</span><span class=\"boring\"> hidden()\n</span> nothidden()\n</code>",
|
||||
),
|
||||
];
|
||||
let mut code = Code::default();
|
||||
code.hidelines.insert("python".to_string(), "~".to_string());
|
||||
for (src, should_be) in &inputs {
|
||||
let got = hide_lines(
|
||||
src,
|
||||
&Code {
|
||||
hidelines: {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("python".to_string(), "~".to_string());
|
||||
map
|
||||
},
|
||||
},
|
||||
);
|
||||
let got = hide_lines(src, &code);
|
||||
assert_eq!(&*got, *should_be);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,9 +409,11 @@ fn chapter_settings_priority() {
|
|||
("cli/inner/index.md", Some(true)),
|
||||
("cli/inner/foo.md", Some(false)),
|
||||
] {
|
||||
let mut settings = SearchChapterSettings::default();
|
||||
settings.enable = enable;
|
||||
assert_eq!(
|
||||
get_chapter_settings(&chapter_configs, Path::new(path)),
|
||||
SearchChapterSettings { enable }
|
||||
settings
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ pub static FONT_AWESOME_OTF: &[u8] = include_bytes!("../../front-end/fonts/FontA
|
|||
/// You should only ever use the static variables directly if you want to
|
||||
/// override the user's theme with the defaults.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[non_exhaustive]
|
||||
pub struct Theme {
|
||||
pub index: Vec<u8>,
|
||||
pub head: Vec<u8>,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ pub trait Preprocessor {
|
|||
/// Extra information for a `Preprocessor` to give them more context when
|
||||
/// processing a book.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct PreprocessorContext {
|
||||
/// The location of the book directory on disk.
|
||||
pub root: PathBuf,
|
||||
|
|
@ -62,8 +63,6 @@ pub struct PreprocessorContext {
|
|||
/// This should not be used outside of mdbook's internals.
|
||||
#[serde(skip)]
|
||||
pub chapter_titles: RefCell<HashMap<PathBuf, String>>,
|
||||
#[serde(skip)]
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
|
||||
impl PreprocessorContext {
|
||||
|
|
@ -75,7 +74,6 @@ impl PreprocessorContext {
|
|||
renderer,
|
||||
mdbook_version: crate::MDBOOK_VERSION.to_string(),
|
||||
chapter_titles: RefCell::new(HashMap::new()),
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ pub trait Renderer {
|
|||
|
||||
/// The context provided to all renderers.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct RenderContext {
|
||||
/// Which version of `mdbook` did this come from (as written in `mdbook`'s
|
||||
/// `Cargo.toml`). Useful if you know the renderer is only compatible with
|
||||
|
|
@ -57,8 +58,6 @@ pub struct RenderContext {
|
|||
/// This should not be used outside of mdbook's internals.
|
||||
#[serde(skip)]
|
||||
pub chapter_titles: HashMap<PathBuf, String>,
|
||||
#[serde(skip)]
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
|
||||
impl RenderContext {
|
||||
|
|
@ -75,7 +74,6 @@ impl RenderContext {
|
|||
root: root.into(),
|
||||
destination: destination.into(),
|
||||
chapter_titles: HashMap::new(),
|
||||
__non_exhaustive: (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ pub fn parse_summary(summary: &str) -> Result<Summary> {
|
|||
|
||||
/// The parsed `SUMMARY.md`, specifying how the book should be laid out.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Summary {
|
||||
/// An optional title for the `SUMMARY.md`, currently just ignored.
|
||||
pub title: Option<String>,
|
||||
|
|
@ -79,6 +80,7 @@ pub struct Summary {
|
|||
///
|
||||
/// This is roughly the equivalent of `[Some section](./path/to/file.md)`.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct Link {
|
||||
/// The name of the chapter.
|
||||
pub name: String,
|
||||
|
|
@ -114,8 +116,9 @@ impl Default for Link {
|
|||
}
|
||||
}
|
||||
|
||||
/// An item in `SUMMARY.md` which could be either a separator or a `Link`.
|
||||
/// An item in `SUMMARY.md`.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub enum SummaryItem {
|
||||
/// A link to a chapter.
|
||||
Link(Link),
|
||||
|
|
|
|||
|
|
@ -146,8 +146,7 @@ mod nop_lib {
|
|||
"parent_names": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"__non_exhaustive": null
|
||||
]
|
||||
}
|
||||
]"##;
|
||||
let input_json = input_json.as_bytes();
|
||||
|
|
|
|||
|
|
@ -167,7 +167,6 @@ fn backends_receive_render_context_via_stdin() {
|
|||
str![[r##"
|
||||
{
|
||||
"book": {
|
||||
"__non_exhaustive": null,
|
||||
"sections": [
|
||||
{
|
||||
"Chapter": {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use crate::prelude::*;
|
||||
use mdbook_core::book::{BookItem, Chapter};
|
||||
use snapbox::file;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
|
||||
fn read_book_index(root: &Path) -> serde_json::Value {
|
||||
let index = root.join("book/searchindex.js");
|
||||
|
|
@ -116,15 +116,7 @@ fn can_disable_individual_chapters() {
|
|||
fn with_no_source_path() {
|
||||
let test = BookTest::from_dir("search/reasonable_search_index");
|
||||
let mut book = test.load_book();
|
||||
let chapter = Chapter {
|
||||
name: "Sample chapter".to_string(),
|
||||
content: "".to_string(),
|
||||
number: None,
|
||||
sub_items: Vec::new(),
|
||||
path: Some(PathBuf::from("sample.html")),
|
||||
source_path: None,
|
||||
parent_names: Vec::new(),
|
||||
};
|
||||
let chapter = Chapter::new("Sample chapter", String::new(), "sample.html", vec![]);
|
||||
book.book.sections.push(BookItem::Chapter(chapter));
|
||||
book.build().unwrap();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue