From 30d3aeb69119a7e41c29b630c209fb1c97ce1c23 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 29 Aug 2025 18:24:44 -0700 Subject: [PATCH] Remove non_exhaustive from Book This removes the `non_exhaustive` attribute from the `Book` and its inner types `BookItem` and `Chapter`. These were added in https://github.com/rust-lang/mdBook/pull/2779. After thinking about it more, I realized that these types cannot be extended in a semver-compatible way, so I am fine with allowing them be exhaustive. The problem is that with CmdPreprocessor, the `Book` will be re-serialized by a preprocessor, which could potentially be on an older version. Attempting to add any new fields/variants means that either the deserialization will fail, or the new fields will be stripped by the preprocessor. These could potentially be structured such that they have a `serde(flatten)` or Other/Unknown variant so that a preprocessor would at least see the extra fields/variants and pass them along back to the output. However, a preprocessor or renderer wouldn't know what to do with those new fields/variants (particularly `BookItem`) which would itself be a problem. It's still possible to do something like this in the future, but for now I think it's fine to restrict these to semver-major changes. --- crates/mdbook-core/src/book.rs | 15 ++++++++++++--- .../src/html_handlebars/hbs_renderer.rs | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/mdbook-core/src/book.rs b/crates/mdbook-core/src/book.rs index e542c8e3..e7fa1368 100644 --- a/crates/mdbook-core/src/book.rs +++ b/crates/mdbook-core/src/book.rs @@ -18,8 +18,11 @@ mod tests; /// /// [`iter()`]: #method.iter /// [`for_each_mut()`]: #method.for_each_mut +#[allow( + clippy::exhaustive_structs, + reason = "This cannot be extended without breaking preprocessors." +)] #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub struct Book { /// The items in this book. pub items: Vec, @@ -80,8 +83,11 @@ where } /// Enum representing any type of item which can be added to a book. +#[allow( + clippy::exhaustive_enums, + reason = "This cannot be extended without breaking preprocessors." +)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub enum BookItem { /// A nested chapter. Chapter(Chapter), @@ -99,8 +105,11 @@ impl From for BookItem { /// The representation of a "chapter", usually mapping to a single file on /// disk however it may contain multiple sub-chapters. +#[allow( + clippy::exhaustive_structs, + reason = "This cannot be extended without breaking preprocessors." +)] #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] pub struct Chapter { /// The chapter's name. pub name: String, diff --git a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs index 7118e3cf..86c16eb1 100644 --- a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs +++ b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs @@ -687,7 +687,6 @@ fn make_data( BookItem::Separator => { chapter.insert("spacer".to_owned(), json!("_spacer_")); } - _ => panic!("BookItem {item:?} not covered"), } chapters.push(chapter);