From 6e85cb945bb6d319bae1cb4c61d51c6e3c02a3ef Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:43:51 +0100 Subject: [PATCH 01/14] lint: move to Cargo.toml --- scraper/Cargo.toml | 10 ++++++++++ scraper/examples/document.rs | 2 -- scraper/examples/fragment.rs | 2 -- scraper/src/lib.rs | 12 +----------- scraper/src/main.rs | 3 --- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 4d85bfde..e89978fb 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -34,6 +34,16 @@ atomic = [] errors = [] serde = ["dep:serde"] +[lints.rust] +missing_copy_implementations = "warn" +missing_debug_implementations = "warn" +trivial_casts = "warn" +trivial_numeric_casts = "warn" +unused_extern_crates = "warn" +unused_import_braces = "warn" +unused_qualifications = "warn" +variant_size_differences = "warn" + [[bin]] name = "scraper" path = "src/main.rs" diff --git a/scraper/examples/document.rs b/scraper/examples/document.rs index e9bd9d1c..92b71a5a 100644 --- a/scraper/examples/document.rs +++ b/scraper/examples/document.rs @@ -1,5 +1,3 @@ -extern crate scraper; - use std::io::{self, Read, Write}; use scraper::{Html, Selector}; diff --git a/scraper/examples/fragment.rs b/scraper/examples/fragment.rs index dff98506..e1c531c2 100644 --- a/scraper/examples/fragment.rs +++ b/scraper/examples/fragment.rs @@ -1,5 +1,3 @@ -extern crate scraper; - use std::io::{self, Read, Write}; use scraper::{Html, Selector}; diff --git a/scraper/src/lib.rs b/scraper/src/lib.rs index be354b1b..62b1170b 100644 --- a/scraper/src/lib.rs +++ b/scraper/src/lib.rs @@ -1,15 +1,5 @@ #![doc = include_str!("../README.md")] -#![warn( - missing_docs, - missing_debug_implementations, - missing_copy_implementations, - trivial_casts, - trivial_numeric_casts, - unused_extern_crates, - unused_import_braces, - unused_qualifications, - variant_size_differences -)] +#![warn(missing_docs)] //! # The core types //! diff --git a/scraper/src/main.rs b/scraper/src/main.rs index 72328670..38572d0d 100644 --- a/scraper/src/main.rs +++ b/scraper/src/main.rs @@ -1,6 +1,3 @@ -extern crate getopts; -extern crate scraper; - use getopts::Options; use scraper::{Html, Selector}; use std::env; From 20ed758076c652dab72a7b65d421295a268ea7ce Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:47:13 +0100 Subject: [PATCH 02/14] lint: redundant_imports --- scraper/Cargo.toml | 1 + scraper/src/selector.rs | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index e89978fb..5ca7571e 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -37,6 +37,7 @@ serde = ["dep:serde"] [lints.rust] missing_copy_implementations = "warn" missing_debug_implementations = "warn" +redundant_imports = "warn" trivial_casts = "warn" trivial_numeric_casts = "warn" unused_extern_crates = "warn" diff --git a/scraper/src/selector.rs b/scraper/src/selector.rs index ab3605d0..cc9a7b84 100644 --- a/scraper/src/selector.rs +++ b/scraper/src/selector.rs @@ -1,6 +1,5 @@ //! CSS selectors. -use std::convert::TryFrom; use std::fmt; use std::str::FromStr; @@ -256,7 +255,6 @@ impl FromStr for Selector { #[cfg(test)] mod tests { use super::*; - use std::convert::TryInto; #[test] fn selector_conversions() { From 24782d3e2bf1fa9c35682d55059eeec97563318e Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:48:11 +0100 Subject: [PATCH 03/14] lint: single_use_lifetimes --- scraper/Cargo.toml | 1 + scraper/src/selector.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 5ca7571e..37278872 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -38,6 +38,7 @@ serde = ["dep:serde"] missing_copy_implementations = "warn" missing_debug_implementations = "warn" redundant_imports = "warn" +single_use_lifetimes = "warn" trivial_casts = "warn" trivial_numeric_casts = "warn" unused_extern_crates = "warn" diff --git a/scraper/src/selector.rs b/scraper/src/selector.rs index cc9a7b84..db47b130 100644 --- a/scraper/src/selector.rs +++ b/scraper/src/selector.rs @@ -115,7 +115,7 @@ impl Visitor<'_> for SelectorVisitor { /// An implementation of `Parser` for `selectors` #[derive(Clone, Copy, Debug)] pub struct Parser; -impl<'i> parser::Parser<'i> for Parser { +impl parser::Parser<'_> for Parser { type Impl = Simple; type Error = SelectorParseErrorKind; From 506d7ae3bb1ea5fde2400921af786e360c61c3ac Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:51:04 +0100 Subject: [PATCH 04/14] clippy::allow_attributes --- scraper/Cargo.toml | 2 ++ scraper/src/node.rs | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 37278872..4791d83d 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -45,6 +45,8 @@ unused_extern_crates = "warn" unused_import_braces = "warn" unused_qualifications = "warn" variant_size_differences = "warn" +[lints.clippy] +allow_attributes = "warn" [[bin]] name = "scraper" diff --git a/scraper/src/node.rs b/scraper/src/node.rs index a1c45af0..388edaae 100644 --- a/scraper/src/node.rs +++ b/scraper/src/node.rs @@ -11,7 +11,6 @@ use std::cell::OnceCell; /// An HTML node. // `Element` is usally the most common variant and hence boxing it // will most likely not improve performance overall. -#[allow(variant_size_differences)] #[derive(Clone, PartialEq, Eq)] pub enum Node { /// The document root. @@ -240,7 +239,7 @@ pub struct Element { impl Element { #[doc(hidden)] pub fn new(name: QualName, attributes: Vec) -> Self { - #[allow(unused_mut)] + #[cfg_attr(feature = "deterministic", expect(unused_mut))] let mut attrs = attributes .into_iter() .map(|attr| (attr.name, crate::tendril_util::make(attr.value))) @@ -327,7 +326,7 @@ impl Element { } /// Iterator over classes. -#[allow(missing_debug_implementations)] +#[expect(missing_debug_implementations)] #[derive(Clone)] pub struct Classes<'a> { inner: SliceIter<'a, LocalName>, @@ -350,7 +349,7 @@ pub type AttributesIter<'a> = indexmap::map::Iter<'a, QualName, StrTendril>; pub type AttributesIter<'a> = SliceIter<'a, (QualName, StrTendril)>; /// Iterator over attributes. -#[allow(missing_debug_implementations)] +#[expect(missing_debug_implementations)] #[derive(Clone)] pub struct Attrs<'a> { inner: AttributesIter<'a>, From 6dde4241407b76bd1982c7221184abf0c7cfd055 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:53:15 +0100 Subject: [PATCH 05/14] clippy::pedantic --- scraper/Cargo.toml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 4791d83d..62c81779 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -46,8 +46,21 @@ unused_import_braces = "warn" unused_qualifications = "warn" variant_size_differences = "warn" [lints.clippy] +pedantic = { level = "warn", priority = -1 } allow_attributes = "warn" +default_trait_access = "allow" +enum_glob_use = "allow" +explicit_deref_methods = "allow" +manual_let_else = "allow" +missing_errors_doc = "allow" +missing_panics_doc = "allow" +must_use_candidate = "allow" +needless_pass_by_value = "allow" +semicolon_if_nothing_returned = "allow" +should_panic_without_expect = "allow" +similar_names = "allow" + [[bin]] name = "scraper" path = "src/main.rs" From 237b07b794e42e09936a24516b9868b2fa0c18a1 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 11:59:31 +0100 Subject: [PATCH 06/14] check lints for multiple feature sets --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd2de507..068089ac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,13 +20,17 @@ jobs: clippy: name: Clippy check runs-on: ubuntu-latest + env: + RUSTFLAGS: --deny warnings steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: clippy - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --all-targets --all-features -- --deny warnings + - run: cargo clippy --all-targets --all-features + - run: cargo clippy --all-targets + - run: cargo clippy --all-targets --no-default-features test: name: Test code From 974e159bd54476961c06cf175b55c89e577fa1af Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:02:19 +0100 Subject: [PATCH 07/14] clippy::enum_glob_use https://rust-lang.github.io/rust-clippy/stable/index.html#enum_glob_use --- scraper/Cargo.toml | 1 - scraper/src/main.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 62c81779..b91f46c9 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -50,7 +50,6 @@ pedantic = { level = "warn", priority = -1 } allow_attributes = "warn" default_trait_access = "allow" -enum_glob_use = "allow" explicit_deref_methods = "allow" manual_let_else = "allow" missing_errors_doc = "allow" diff --git a/scraper/src/main.rs b/scraper/src/main.rs index 38572d0d..dbd8c14c 100644 --- a/scraper/src/main.rs +++ b/scraper/src/main.rs @@ -35,7 +35,7 @@ fn query(input: &Input, output: &Output, selector: &Selector, file: &mu let mut matched = false; for element in html.select(selector) { - use crate::Output::*; + use crate::Output::{Attr, Classes, Html, Id, InnerHtml, Name, Text}; match *output { Html => println!("{}", element.html()), InnerHtml => println!("{}", element.inner_html()), From 9eacbe61dfffe12ea9e8597083c4da1bcd4297d4 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:02:21 +0100 Subject: [PATCH 08/14] clippy::explicit_deref_methods https://rust-lang.github.io/rust-clippy/stable/index.html#explicit_deref_methods --- scraper/Cargo.toml | 1 - scraper/src/node.rs | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index b91f46c9..73bd040b 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -50,7 +50,6 @@ pedantic = { level = "warn", priority = -1 } allow_attributes = "warn" default_trait_access = "allow" -explicit_deref_methods = "allow" manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" diff --git a/scraper/src/node.rs b/scraper/src/node.rs index 388edaae..ee5d74c1 100644 --- a/scraper/src/node.rs +++ b/scraper/src/node.rs @@ -138,17 +138,17 @@ pub struct Doctype { impl Doctype { /// Returns the doctype name. pub fn name(&self) -> &str { - self.name.deref() + &self.name } /// Returns the doctype public ID. pub fn public_id(&self) -> &str { - self.public_id.deref() + &self.public_id } /// Returns the doctype system ID. pub fn system_id(&self) -> &str { - self.system_id.deref() + &self.system_id } } @@ -181,7 +181,7 @@ impl Deref for Comment { impl fmt::Debug for Comment { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "", self.deref()) + write!(f, "", &**self) } } @@ -202,7 +202,7 @@ impl Deref for Text { impl fmt::Debug for Text { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{:?}", self.deref()) + write!(f, "{:?}", &**self) } } @@ -258,7 +258,7 @@ impl Element { /// Returns the element name. pub fn name(&self) -> &str { - self.name.local.deref() + &self.name.local } /// Returns the element ID. @@ -359,7 +359,7 @@ impl<'a> Iterator for Attrs<'a> { type Item = (&'a str, &'a str); fn next(&mut self) -> Option<(&'a str, &'a str)> { - self.inner.next().map(|(k, v)| (k.local.deref(), v.deref())) + self.inner.next().map(|(k, v)| (&*k.local, &**v)) } } From cca4ca632bf324677443f6dcf6c688eef0086de8 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:02:25 +0100 Subject: [PATCH 09/14] clippy::semicolon_if_nothing_returned https://rust-lang.github.io/rust-clippy/stable/index.html#semicolon_if_nothing_returned --- scraper/Cargo.toml | 1 - scraper/src/html/tree_sink.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 73bd040b..4bf200fd 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -55,7 +55,6 @@ missing_errors_doc = "allow" missing_panics_doc = "allow" must_use_candidate = "allow" needless_pass_by_value = "allow" -semicolon_if_nothing_returned = "allow" should_panic_without_expect = "allow" similar_names = "allow" diff --git a/scraper/src/html/tree_sink.rs b/scraper/src/html/tree_sink.rs index 10136ec9..f391aaf9 100644 --- a/scraper/src/html/tree_sink.rs +++ b/scraper/src/html/tree_sink.rs @@ -289,9 +289,9 @@ impl TreeSink for HtmlTreeSink { .is_some(); if has_parent { - self.append_before_sibling(element, child) + self.append_before_sibling(element, child); } else { - self.append(prev_element, child) + self.append(prev_element, child); } } } From b76165af6dcd6e43db66d53ad96ade2ad92df524 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:10:24 +0100 Subject: [PATCH 10/14] clippy::needless_pass_by_value --- scraper/Cargo.toml | 1 - scraper/src/node/serializable.rs | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 4bf200fd..b40f7d26 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -54,7 +54,6 @@ manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" must_use_candidate = "allow" -needless_pass_by_value = "allow" should_panic_without_expect = "allow" similar_names = "allow" diff --git a/scraper/src/node/serializable.rs b/scraper/src/node/serializable.rs index 724dedf2..30b84706 100644 --- a/scraper/src/node/serializable.rs +++ b/scraper/src/node/serializable.rs @@ -6,6 +6,10 @@ use html5ever::serialize::{Serializer, TraversalScope}; use crate::Node; /// Serialize an HTML node using html5ever serializer. +#[expect( + clippy::needless_pass_by_value, + reason = "same as html5ever Serialize trait" +)] pub(crate) fn serialize( self_node: NodeRef, serializer: &mut S, From 2f81945fb40bf8ec4c8b25d5e54c78bae1be0b2b Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:12:45 +0100 Subject: [PATCH 11/14] clippy::should_panic_without_expect --- scraper/Cargo.toml | 1 - scraper/src/selector.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index b40f7d26..68b772ca 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -54,7 +54,6 @@ manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" must_use_candidate = "allow" -should_panic_without_expect = "allow" similar_names = "allow" [[bin]] diff --git a/scraper/src/selector.rs b/scraper/src/selector.rs index db47b130..5c7d1ab8 100644 --- a/scraper/src/selector.rs +++ b/scraper/src/selector.rs @@ -266,7 +266,7 @@ mod tests { } #[test] - #[should_panic] + #[should_panic = "UnexpectedSelectorParseError"] fn invalid_selector_conversions() { let s = ""; let _sel: Selector = s.try_into().unwrap(); From 31e18545b805a3300cf69c0df34015ea2775dac6 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:16:11 +0100 Subject: [PATCH 12/14] clippy::similar_names --- scraper/Cargo.toml | 1 - scraper/src/main.rs | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 68b772ca..4aa94c56 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -54,7 +54,6 @@ manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" must_use_candidate = "allow" -similar_names = "allow" [[bin]] name = "scraper" diff --git a/scraper/src/main.rs b/scraper/src/main.rs index dbd8c14c..a90500a6 100644 --- a/scraper/src/main.rs +++ b/scraper/src/main.rs @@ -33,7 +33,7 @@ fn query(input: &Input, output: &Output, selector: &Selector, file: &mu Input::Fragment => Html::parse_fragment(&html), }; - let mut matched = false; + let mut has_matches = false; for element in html.select(selector) { use crate::Output::{Attr, Classes, Html, Id, InnerHtml, Name, Text}; match *output { @@ -48,9 +48,9 @@ fn query(input: &Input, output: &Output, selector: &Selector, file: &mu Name => println!("{}", element.value().name()), Text => println!("{}", element.text().collect::()), } - matched = true; + has_matches = true; } - matched + has_matches } fn main() { @@ -132,7 +132,7 @@ fn main() { process::exit(USAGE); }); - let matched = if files.is_empty() { + let selector_has_matches = if files.is_empty() { query(&input, &output, &selector, &mut io::stdin()) } else { files @@ -142,5 +142,5 @@ fn main() { .any(|mut f| query(&input, &output, &selector, &mut f)) }; - process::exit(i32::from(!matched)); + process::exit(i32::from(!selector_has_matches)); } From 03058b27eb528c07843d14daf92e493c9f852e9b Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:19:25 +0100 Subject: [PATCH 13/14] clippy::default_trait_access --- scraper/Cargo.toml | 1 - scraper/src/element_ref/mod.rs | 4 ++-- scraper/src/html/mod.rs | 10 ++++++---- scraper/src/selector.rs | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index 4aa94c56..fc820ea0 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -49,7 +49,6 @@ variant_size_differences = "warn" pedantic = { level = "warn", priority = -1 } allow_attributes = "warn" -default_trait_access = "allow" manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" diff --git a/scraper/src/element_ref/mod.rs b/scraper/src/element_ref/mod.rs index b00dd8f2..d8534bf9 100644 --- a/scraper/src/element_ref/mod.rs +++ b/scraper/src/element_ref/mod.rs @@ -49,7 +49,7 @@ impl<'a> ElementRef<'a> { scope: *self, inner, selector, - caches: Default::default(), + caches: SelectorCaches::default(), } } @@ -154,7 +154,7 @@ impl Clone for Select<'_, '_> { scope: self.scope, inner: self.inner.clone(), selector: self.selector, - caches: Default::default(), + caches: SelectorCaches::default(), } } } diff --git a/scraper/src/html/mod.rs b/scraper/src/html/mod.rs index 0722c693..983fac24 100644 --- a/scraper/src/html/mod.rs +++ b/scraper/src/html/mod.rs @@ -76,8 +76,10 @@ impl Html { /// # } /// ``` pub fn parse_document(document: &str) -> Self { - let parser = - driver::parse_document(HtmlTreeSink::new(Self::new_document()), Default::default()); + let parser = driver::parse_document( + HtmlTreeSink::new(Self::new_document()), + ParseOpts::default(), + ); parser.one(document) } @@ -100,7 +102,7 @@ impl Html { Select { inner: self.tree.nodes(), selector, - caches: Default::default(), + caches: SelectorCaches::default(), } } @@ -149,7 +151,7 @@ impl Clone for Select<'_, '_> { Self { inner: self.inner.clone(), selector: self.selector, - caches: Default::default(), + caches: SelectorCaches::default(), } } } diff --git a/scraper/src/selector.rs b/scraper/src/selector.rs index 5c7d1ab8..0be37a6c 100644 --- a/scraper/src/selector.rs +++ b/scraper/src/selector.rs @@ -45,7 +45,7 @@ impl Selector { /// The optional `scope` argument is used to specify which element has `:scope` pseudo-class. /// When it is `None`, `:scope` will match the root element. pub fn matches_with_scope(&self, element: &ElementRef, scope: Option) -> bool { - self.matches_with_scope_and_cache(element, scope, &mut Default::default()) + self.matches_with_scope_and_cache(element, scope, &mut matching::SelectorCaches::default()) } // The `nth_index_cache` must not be used after `self` is dropped From 2aa0467577ed47ef8ad8395696faff79b4c9f384 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Tue, 3 Nov 2026 12:21:41 +0100 Subject: [PATCH 14/14] clippy::manual_let_else --- scraper/Cargo.toml | 1 - scraper/src/html/tree_sink.rs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scraper/Cargo.toml b/scraper/Cargo.toml index fc820ea0..0e64a53a 100644 --- a/scraper/Cargo.toml +++ b/scraper/Cargo.toml @@ -49,7 +49,6 @@ variant_size_differences = "warn" pedantic = { level = "warn", priority = -1 } allow_attributes = "warn" -manual_let_else = "allow" missing_errors_doc = "allow" missing_panics_doc = "allow" must_use_candidate = "allow" diff --git a/scraper/src/html/tree_sink.rs b/scraper/src/html/tree_sink.rs index f391aaf9..7aefd41d 100644 --- a/scraper/src/html/tree_sink.rs +++ b/scraper/src/html/tree_sink.rs @@ -217,9 +217,8 @@ impl TreeSink for HtmlTreeSink { fn add_attrs_if_missing(&self, target: &Self::Handle, attrs: Vec) { let mut this = self.0.borrow_mut(); let mut node = this.tree.get_mut(*target).unwrap(); - let element = match *node.value() { - Node::Element(ref mut e) => e, - _ => unreachable!(), + let Node::Element(ref mut element) = *node.value() else { + unreachable!() }; for attr in attrs {