summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2023-09-10 10:37:18 +0200
committerMartin Fischer <martin@push-f.com>2023-09-28 10:36:08 +0200
commit55729998c2217bfdbbccf9832b29d3bcd0315094 (patch)
treede17a8da482a650eab7101e31f1c555dd15f8e4c
parent3bcbdbae41c67dd41333097cd405dcdc26fce67f (diff)
refactor: simplify attribute logic in DefaultEmitter
-rw-r--r--src/default_emitter.rs42
-rw-r--r--src/token.rs2
2 files changed, 18 insertions, 26 deletions
diff --git a/src/default_emitter.rs b/src/default_emitter.rs
index 1559021..7b6c51e 100644
--- a/src/default_emitter.rs
+++ b/src/default_emitter.rs
@@ -13,18 +13,20 @@ use crate::Error;
/// The default implementation of [`Emitter`], used to produce tokens.
pub struct DefaultEmitter<O = NoopOffset> {
current_token: Option<Token<O>>,
- current_attribute: Option<(String, crate::token::AttrInternal<O>)>,
+ current_attribute_name: String,
+ current_attr_internal: crate::token::AttrInternal<O>,
seen_attributes: BTreeSet<String>,
emitted_tokens: VecDeque<Token<O>>,
errors: VecDeque<(Error, Range<O>)>,
attr_in_end_tag_span: Option<Range<O>>,
}
-impl<O> Default for DefaultEmitter<O> {
+impl<O: Default> Default for DefaultEmitter<O> {
fn default() -> Self {
DefaultEmitter {
current_token: None,
- current_attribute: None,
+ current_attribute_name: String::new(),
+ current_attr_internal: Default::default(),
seen_attributes: BTreeSet::new(),
emitted_tokens: VecDeque::new(),
errors: VecDeque::new(),
@@ -101,41 +103,28 @@ impl<O: Offset> Emitter<O> for DefaultEmitter<O> {
fn init_attribute_name(&mut self, offset: O) {
self.flush_current_attribute();
- self.current_attribute = Some((
- String::new(),
- crate::token::AttrInternal {
- name_span: offset..O::default(),
- value: String::new(),
- value_span: O::default()..O::default(),
- value_syntax: None,
- },
- ));
+ self.current_attr_internal.name_span.start = offset;
}
fn push_attribute_name(&mut self, s: &str) {
- let current_attr = self.current_attribute.as_mut().unwrap();
- current_attr.0.push_str(s);
+ self.current_attribute_name.push_str(s);
}
fn terminate_attribute_name(&mut self, offset: O) {
- let current_attr = self.current_attribute.as_mut().unwrap();
- current_attr.1.name_span.end = offset;
+ self.current_attr_internal.name_span.end = offset;
}
fn init_attribute_value(&mut self, syntax: AttrValueSyntax, offset: O) {
- let (_, current_attribute) = self.current_attribute.as_mut().unwrap();
- current_attribute.value_span.start = offset;
- current_attribute.value_syntax = Some(syntax);
+ self.current_attr_internal.value_span.start = offset;
+ self.current_attr_internal.value_syntax = Some(syntax);
}
fn push_attribute_value(&mut self, s: &str) {
- let current_attr = self.current_attribute.as_mut().unwrap();
- current_attr.1.value.push_str(s);
+ self.current_attr_internal.value.push_str(s);
}
fn terminate_attribute_value(&mut self, offset: O) {
- let current_attr = self.current_attribute.as_mut().unwrap();
- current_attr.1.value_span.end = offset;
+ self.current_attr_internal.value_span.end = offset;
}
fn set_self_closing(&mut self, slash_span: Range<O>) {
@@ -294,9 +283,12 @@ impl<O> DefaultEmitter<O> {
where
O: Offset,
{
- let Some((name, attr_internal)) = self.current_attribute.take() else {
+ if self.current_attribute_name.is_empty() {
return;
- };
+ }
+ let name = std::mem::take(&mut self.current_attribute_name);
+ let attr_internal = std::mem::take(&mut self.current_attr_internal);
+
match &mut self.current_token {
Some(Token::StartTag(tag)) => match tag.attributes.inner.entry(name) {
Entry::Vacant(vacant) => {
diff --git a/src/token.rs b/src/token.rs
index 3104a61..ed8c8c8 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -155,7 +155,7 @@ pub struct AttributeMap<O> {
/// The value type internally used by the [`AttributeMap`].
/// Not part of the public API.
-#[derive(Debug, Eq, PartialEq)]
+#[derive(Default, Debug, Eq, PartialEq)]
pub(crate) struct AttrInternal<O> {
pub value: String,
/// The span of the attribute name.