Skip to content

Commit 396f68a

Browse files
authored
Make return type of TreeSink::elem_name an associated type. (#553)
* Allow clippy::enum_variant_names to avoid a breaking change Signed-off-by: Nico Burns <nico@nicoburns.com> * Fix clippy::too_long_first_doc_paragraph lint Signed-off-by: Nico Burns <nico@nicoburns.com> * Make return type of `TreeSink::elem_name` an associated type. This allows this type to be owned or contain data protected by a RefCell or Mutex. It can also simply be `ExpandedName` - the type which was previously the return type of `TreeSink::elem_name` Signed-off-by: Nico Burns <nico@nicoburns.com> --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
1 parent bb62eac commit 396f68a

File tree

12 files changed

+133
-46
lines changed

12 files changed

+133
-46
lines changed

html5ever/examples/arena.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extern crate typed_arena;
1212

1313
use html5ever::interface::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
1414
use html5ever::tendril::{StrTendril, TendrilSink};
15-
use html5ever::{parse_document, Attribute, ExpandedName, QualName};
15+
use html5ever::{parse_document, Attribute, QualName};
1616
use std::borrow::Cow;
1717
use std::cell::{Cell, RefCell};
1818
use std::collections::HashSet;
@@ -183,6 +183,7 @@ impl<'arena> Sink<'arena> {
183183
impl<'arena> TreeSink for Sink<'arena> {
184184
type Handle = Ref<'arena>;
185185
type Output = Ref<'arena>;
186+
type ElemName<'a> = &'a QualName where Self : 'a;
186187

187188
fn finish(self) -> Ref<'arena> {
188189
self.document
@@ -202,9 +203,9 @@ impl<'arena> TreeSink for Sink<'arena> {
202203
ptr::eq::<Node>(*x, *y)
203204
}
204205

205-
fn elem_name<'a>(&self, target: &'a Ref<'arena>) -> ExpandedName<'a> {
206+
fn elem_name(&self, target: &Ref<'arena>) -> Self::ElemName<'_> {
206207
match target.data {
207-
NodeData::Element { ref name, .. } => name.expanded(),
208+
NodeData::Element { ref name, .. } => name,
208209
_ => panic!("not an element!"),
209210
}
210211
}

html5ever/examples/noop-tree-builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ impl Sink {
4040
impl TreeSink for Sink {
4141
type Handle = usize;
4242
type Output = Self;
43+
type ElemName<'a> = ExpandedName<'a>;
4344
fn finish(self) -> Self {
4445
self
4546
}

html5ever/examples/print-tree-actions.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
extern crate html5ever;
1212

1313
use std::borrow::Cow;
14-
use std::cell::{Cell, RefCell};
14+
use std::cell::{Cell, Ref, RefCell};
1515
use std::collections::HashMap;
1616
use std::io;
1717

@@ -20,7 +20,7 @@ use html5ever::tendril::*;
2020
use html5ever::tree_builder::{
2121
AppendNode, AppendText, ElementFlags, NodeOrText, QuirksMode, TreeSink,
2222
};
23-
use html5ever::{Attribute, ExpandedName, QualName};
23+
use html5ever::{Attribute, QualName};
2424

2525
struct Sink {
2626
next_id: Cell<usize>,
@@ -38,6 +38,7 @@ impl Sink {
3838
impl TreeSink for Sink {
3939
type Handle = usize;
4040
type Output = Self;
41+
type ElemName<'a> = Ref<'a, QualName>;
4142
fn finish(self) -> Self {
4243
self
4344
}
@@ -68,13 +69,10 @@ impl TreeSink for Sink {
6869
x == y
6970
}
7071

71-
fn elem_name(&self, target: &usize) -> ExpandedName {
72-
self.names
73-
.borrow()
74-
.get(target)
75-
.cloned()
76-
.expect("not an element")
77-
.expanded()
72+
fn elem_name(&self, target: &usize) -> Self::ElemName<'_> {
73+
Ref::map(self.names.borrow(), |map| {
74+
*map.get(target).expect("not an element")
75+
})
7876
}
7977

8078
fn create_element(&self, name: QualName, _: Vec<Attribute>, _: ElementFlags) -> usize {

html5ever/src/tree_builder/mod.rs

+27-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
//! The HTML5 tree builder.
1111
12-
pub use crate::interface::{create_element, ElementFlags, NextParserState, Tracer, TreeSink};
12+
pub use crate::interface::{
13+
create_element, ElemName, ElementFlags, NextParserState, Tracer, TreeSink,
14+
};
1315
pub use crate::interface::{AppendNode, AppendText, Attribute, NodeOrText};
1416
pub use crate::interface::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
1517

@@ -187,7 +189,8 @@ where
187189
opts: TreeBuilderOpts,
188190
) -> TreeBuilder<Handle, Sink> {
189191
let doc_handle = sink.get_document();
190-
let context_is_template = sink.elem_name(&context_elem) == expanded_name!(html "template");
192+
let context_is_template =
193+
sink.elem_name(&context_elem).expanded() == expanded_name!(html "template");
191194
let template_modes = if context_is_template {
192195
RefCell::new(vec![InTemplate])
193196
} else {
@@ -231,7 +234,8 @@ where
231234
pub fn tokenizer_state_for_context_elem(&self) -> tok_state::State {
232235
let context_elem = self.context_elem.borrow();
233236
let elem = context_elem.as_ref().expect("no context element");
234-
let name = match self.sink.elem_name(elem) {
237+
let elem_name = self.sink.elem_name(elem);
238+
let name = match elem_name.expanded() {
235239
ExpandedName {
236240
ns: &ns!(html),
237241
local,
@@ -296,8 +300,8 @@ where
296300
print!(" open_elems:");
297301
for node in self.open_elems.borrow().iter() {
298302
let name = self.sink.elem_name(node);
299-
match *name.ns {
300-
ns!(html) => print!(" {}", name.local),
303+
match *name.ns() {
304+
ns!(html) => print!(" {}", name.local_name()),
301305
_ => panic!(),
302306
}
303307
}
@@ -308,8 +312,8 @@ where
308312
&Marker => print!(" Marker"),
309313
Element(h, _) => {
310314
let name = self.sink.elem_name(h);
311-
match *name.ns {
312-
ns!(html) => print!(" {}", name.local),
315+
match *name.ns() {
316+
ns!(html) => print!(" {}", name.local_name()),
313317
_ => panic!(),
314318
}
315319
},
@@ -541,7 +545,7 @@ where
541545

542546
fn adjusted_current_node_present_but_not_in_html_namespace(&self) -> bool {
543547
!self.open_elems.borrow().is_empty()
544-
&& self.sink.elem_name(&self.adjusted_current_node()).ns != &ns!(html)
548+
&& *self.sink.elem_name(&self.adjusted_current_node()).ns() != ns!(html)
545549
}
546550
}
547551

@@ -689,7 +693,7 @@ where
689693
where
690694
TagSet: Fn(ExpandedName) -> bool,
691695
{
692-
set(self.sink.elem_name(&self.current_node()))
696+
set(self.sink.elem_name(&self.current_node()).expanded())
693697
}
694698

695699
// Insert at the "appropriate place for inserting a node".
@@ -1014,7 +1018,8 @@ where
10141018
for elem in self.open_elems.borrow().iter() {
10151019
let error;
10161020
{
1017-
let name = self.sink.elem_name(elem);
1021+
let elem_name = self.sink.elem_name(elem);
1022+
let name = elem_name.expanded();
10181023
if body_end_ok(name) {
10191024
continue;
10201025
}
@@ -1041,7 +1046,7 @@ where
10411046
if pred(node.clone()) {
10421047
return true;
10431048
}
1044-
if scope(self.sink.elem_name(node)) {
1049+
if scope(self.sink.elem_name(node).expanded()) {
10451050
return false;
10461051
}
10471052
}
@@ -1055,12 +1060,12 @@ where
10551060
where
10561061
TagSet: Fn(ExpandedName) -> bool,
10571062
{
1058-
set(self.sink.elem_name(elem))
1063+
set(self.sink.elem_name(elem).expanded())
10591064
}
10601065

10611066
fn html_elem_named(&self, elem: &Handle, name: LocalName) -> bool {
1062-
let expanded = self.sink.elem_name(elem);
1063-
*expanded.ns == ns!(html) && *expanded.local == name
1067+
let elem_name = self.sink.elem_name(elem);
1068+
*elem_name.ns() == ns!(html) && *elem_name.local_name() == name
10641069
}
10651070

10661071
fn in_html_elem_named(&self, name: LocalName) -> bool {
@@ -1090,8 +1095,8 @@ where
10901095
{
10911096
let open_elems = self.open_elems.borrow();
10921097
let elem = unwrap_or_return!(open_elems.last());
1093-
let nsname = self.sink.elem_name(elem);
1094-
if !set(nsname) {
1098+
let elem_name = self.sink.elem_name(elem);
1099+
if !set(elem_name.expanded()) {
10951100
return;
10961101
}
10971102
}
@@ -1132,7 +1137,7 @@ where
11321137
match self.open_elems.borrow_mut().pop() {
11331138
None => break,
11341139
Some(elem) => {
1135-
if pred(self.sink.elem_name(&elem)) {
1140+
if pred(self.sink.elem_name(&elem).expanded()) {
11361141
break;
11371142
}
11381143
},
@@ -1217,7 +1222,8 @@ where
12171222
if let (true, Some(ctx)) = (last, context_elem.as_ref()) {
12181223
node = ctx;
12191224
}
1220-
let name = match self.sink.elem_name(node) {
1225+
let elem_name = self.sink.elem_name(node);
1226+
let name = match elem_name.expanded() {
12211227
ExpandedName {
12221228
ns: &ns!(html),
12231229
local,
@@ -1470,7 +1476,8 @@ where
14701476
}
14711477

14721478
let current = self.adjusted_current_node();
1473-
let name = self.sink.elem_name(&current);
1479+
let elem_name = self.sink.elem_name(&current);
1480+
let name = elem_name.expanded();
14741481
if let ns!(html) = *name.ns {
14751482
return false;
14761483
}
@@ -1681,7 +1688,7 @@ where
16811688
let current_ns = self
16821689
.sink
16831690
.elem_name(&self.adjusted_current_node())
1684-
.ns
1691+
.ns()
16851692
.clone();
16861693
match current_ns {
16871694
ns!(mathml) => self.adjust_mathml_attributes(&mut tag),

html5ever/src/tree_builder/rules.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@
99

1010
// The tree builder rules, as a single, enormous nested match expression.
1111

12-
use markup5ever::{expanded_name, local_name, namespace_prefix, namespace_url, ns};
12+
use crate::interface::Quirks;
1313
use crate::tokenizer::states::{Plaintext, Rawtext, Rcdata, ScriptData};
14+
use crate::tokenizer::TagKind::{EndTag, StartTag};
1415
use crate::tree_builder::tag_sets::*;
1516
use crate::tree_builder::types::*;
17+
use crate::tree_builder::{
18+
create_element, html_elem, ElemName, NodeOrText::AppendNode, StrTendril, Tag, TreeBuilder,
19+
TreeSink,
20+
};
1621
use crate::QualName;
17-
use crate::tree_builder::{create_element, html_elem, TreeSink, Tag, NodeOrText::AppendNode, StrTendril, TreeBuilder};
18-
use crate::tokenizer::TagKind::{StartTag, EndTag};
22+
use markup5ever::{expanded_name, local_name, namespace_prefix, namespace_url, ns};
1923
use std::borrow::Cow::Borrowed;
20-
use crate::interface::Quirks;
2124

2225
use std::borrow::ToOwned;
2326

@@ -402,7 +405,8 @@ where
402405

403406
let mut to_close = None;
404407
for node in self.open_elems.borrow().iter().rev() {
405-
let name = self.sink.elem_name(node);
408+
let elem_name = self.sink.elem_name(node);
409+
let name = elem_name.expanded();
406410
let can_close = if list {
407411
close_list(name)
408412
} else {
@@ -1441,8 +1445,8 @@ where
14411445
{
14421446
let open_elems = self.open_elems.borrow();
14431447
let node_name = self.sink.elem_name(&open_elems[stack_idx]);
1444-
html = *node_name.ns == ns!(html);
1445-
eq = node_name.local.eq_ignore_ascii_case(&tag.name);
1448+
html = *node_name.ns() == ns!(html);
1449+
eq = node_name.local_name().eq_ignore_ascii_case(&tag.name);
14461450
}
14471451
if !first && html {
14481452
let mode = self.mode.get();

html5ever/src/tree_builder/types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub(crate) enum SplitStatus {
5858
/// A subset/refinement of `tokenizer::Token`. Everything else is handled
5959
/// specially at the beginning of `process_token`.
6060
#[derive(PartialEq, Eq, Clone, Debug)]
61+
#[allow(clippy::enum_variant_names)]
6162
pub(crate) enum Token {
6263
TagToken(Tag),
6364
CommentToken(StrTendril),

markup5ever/interface/mod.rs

+50-1
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
// except according to those terms.
99
//! Types for tag and attribute names, and tree-builder functionality.
1010
11+
use std::cell::Ref;
1112
use std::fmt;
1213
use tendril::StrTendril;
1314

1415
pub use self::tree_builder::{create_element, AppendNode, AppendText, ElementFlags, NodeOrText};
16+
pub use self::tree_builder::{ElemName, NextParserState, Tracer, TreeSink};
1517
pub use self::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
16-
pub use self::tree_builder::{NextParserState, Tracer, TreeSink};
1718
use super::{LocalName, Namespace, Prefix};
1819

1920
/// An [expanded name], containing the tag and the namespace.
@@ -25,6 +26,30 @@ pub struct ExpandedName<'a> {
2526
pub local: &'a LocalName,
2627
}
2728

29+
impl<'a> ElemName for ExpandedName<'a> {
30+
#[inline(always)]
31+
fn ns(&self) -> &Namespace {
32+
self.ns
33+
}
34+
35+
#[inline(always)]
36+
fn local_name(&self) -> &LocalName {
37+
self.local
38+
}
39+
}
40+
41+
impl<'a> ElemName for Ref<'a, ExpandedName<'a>> {
42+
#[inline(always)]
43+
fn ns(&self) -> &Namespace {
44+
self.ns
45+
}
46+
47+
#[inline(always)]
48+
fn local_name(&self) -> &LocalName {
49+
self.local
50+
}
51+
}
52+
2853
impl<'a> fmt::Debug for ExpandedName<'a> {
2954
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3055
if self.ns.is_empty() {
@@ -241,6 +266,30 @@ pub struct QualName {
241266
pub local: LocalName,
242267
}
243268

269+
impl<'a> ElemName for Ref<'a, QualName> {
270+
#[inline(always)]
271+
fn ns(&self) -> &Namespace {
272+
&self.ns
273+
}
274+
275+
#[inline(always)]
276+
fn local_name(&self) -> &LocalName {
277+
&self.local
278+
}
279+
}
280+
281+
impl<'a> ElemName for &'a QualName {
282+
#[inline(always)]
283+
fn ns(&self) -> &Namespace {
284+
&self.ns
285+
}
286+
287+
#[inline(always)]
288+
fn local_name(&self) -> &LocalName {
289+
&self.local
290+
}
291+
}
292+
244293
impl QualName {
245294
/// Basic constructor function.
246295
///

0 commit comments

Comments
 (0)