Skip to content

Commit 51507cc

Browse files
tamer: ir::xir: Combine Token::{SelfClose, Close} variants
This removes `SelfClose` and merges it with `Close` by making the first parameter an `Option`. This isn't really ideal, but it really simplifies pattern matching, especially for the next commit. I'll have more details there. The primary motivation was lack of stabalization for binding after `@` in matches, e.g. `Foo(name, ele) | ele @ Element { name, .. }`. It looks like it's ready, though; maybe next Rust release? rust-lang/rust#65490 I don't know if I'll revert this change after then. This seems plenty clear, albeit more verbose.
1 parent 1c40b9c commit 51507cc

File tree

3 files changed

+32
-38
lines changed

3 files changed

+32
-38
lines changed

tamer/src/ir/xir.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,8 @@ pub enum Token<Ix: SymbolIndexSize> {
363363

364364
/// Closing tag of an element.
365365
///
366-
/// If no child nodes have been encountered since the last `Open`,
367-
/// then the tag is assumed to be self-closing;
368-
/// if this is not desired,
369-
/// emit an empty `Text` variant.
370-
Close(QName<Ix>, Span),
371-
372-
/// End of self-closing tag.
373-
///
366+
/// If the name is [`None`],
367+
/// then the tag is self-closing.
374368
/// This is intended primarily as a safety measure:
375369
/// It allows writers to act as simple state machines without having
376370
/// to ensure balancing by indicating that a node was intended to
@@ -383,7 +377,13 @@ pub enum Token<Ix: SymbolIndexSize> {
383377
/// Instead of losing tags,
384378
/// writers can error,
385379
/// indicating a bug in the stream.
386-
SelfClose(Span),
380+
///
381+
/// The reason for using an option here rather than a variant is to
382+
/// simplify pattern matching,
383+
/// given especially that bindings after `@` in patterns have not
384+
/// yet been stabalized at the time of writing (but are very
385+
/// close!).
386+
Close(Option<QName<Ix>>, Span),
387387

388388
/// Element attribute name
389389
AttrName(QName<Ix>, Span),

tamer/src/ir/xir/tree.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
//! Parsing operates on _context_.
140140
//! At present, the only parsing context is an element---it
141141
//! begins parsing at an opening tag ([`Token::Open`]) and completes
142-
//! parsing at a _matching_ [`Token::Close`] or [`Token::SelfClose`].
142+
//! parsing at a _matching_ [`Token::Close`].
143143
//! All attributes and child nodes encountered during parsing of an element
144144
//! will automatically be added to the appropriate element,
145145
//! recursively.
@@ -386,19 +386,14 @@ impl<Ix: SymbolIndexSize> ParserState<Ix> {
386386
Ok(Parsed::Incomplete)
387387
}
388388

389-
(Token::SelfClose(span), Stack::BuddingElement(ele)) => {
390-
Ok(Parsed::Object(Tree::Element(Element {
391-
span: (ele.span.0, span),
392-
..ele
393-
})))
394-
}
395-
396-
(Token::Close(name, span), Stack::BuddingElement(ele)) => {
397-
if name != ele.name {
398-
return Err(ParseError::UnbalancedTagName {
399-
open: (ele.name, ele.span.0),
400-
close: (name, span),
401-
});
389+
(Token::Close(balance_name, span), Stack::BuddingElement(ele)) => {
390+
if let Some(name) = balance_name {
391+
if name != ele.name {
392+
return Err(ParseError::UnbalancedTagName {
393+
open: (ele.name, ele.span.0),
394+
close: (name, span),
395+
});
396+
}
402397
}
403398

404399
Ok(Parsed::Object(Tree::Element(Element {
@@ -603,7 +598,7 @@ mod test {
603598

604599
let toks = std::array::IntoIter::new([
605600
Token::<Ix>::Open(name, *S),
606-
Token::<Ix>::SelfClose(*S2),
601+
Token::<Ix>::Close(None, *S2),
607602
]);
608603

609604
let expected = Element {
@@ -631,7 +626,7 @@ mod test {
631626

632627
let toks = std::array::IntoIter::new([
633628
Token::<Ix>::Open(name, *S),
634-
Token::<Ix>::Close(name, *S2),
629+
Token::<Ix>::Close(Some(name), *S2),
635630
]);
636631

637632
let expected = Element {
@@ -660,7 +655,7 @@ mod test {
660655

661656
let toks = std::array::IntoIter::new([
662657
Token::<Ix>::Open(open_name, *S),
663-
Token::<Ix>::Close(close_name, *S2),
658+
Token::<Ix>::Close(Some(close_name), *S2),
664659
]);
665660

666661
let mut sut = toks.scan(ParserState::new(), parse);
@@ -692,7 +687,7 @@ mod test {
692687
Token::AttrValue(val1, *S2),
693688
Token::AttrName(attr2, *S),
694689
Token::AttrValue(val2, *S2),
695-
Token::SelfClose(*S2),
690+
Token::Close(None, *S2),
696691
]);
697692

698693
let expected = Element {
@@ -737,7 +732,7 @@ mod test {
737732
Token::<Ix>::Open(name, *S),
738733
Token::AttrName(attr, *S),
739734
Token::AttrValue(val, *S2),
740-
Token::SelfClose(*S2),
735+
Token::Close(None, *S2),
741736
]);
742737

743738
let expected = Element {

tamer/src/ir/xir/writer.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,13 @@ impl<Ix: SymbolIndexSize> XmlWriter for Token<Ix> {
181181
Ok(S::NodeOpen)
182182
}
183183

184-
// TODO: Remove whitespace from here, add to stream, then it can
185-
// be used with attrs
186-
(Self::SelfClose(_), S::NodeOpen) => {
184+
(Self::Close(None, _), S::NodeOpen) => {
187185
sink.write(b"/>")?;
188186

189187
Ok(S::NodeExpected)
190188
}
191189

192-
(Self::Close(name, _), S::NodeExpected | S::NodeOpen) => {
190+
(Self::Close(Some(name), _), S::NodeExpected | S::NodeOpen) => {
193191
// If open, we're going to produce an element of the form
194192
// `<foo></foo>`.
195193
prev_state.close_tag_if_open(sink)?;
@@ -355,7 +353,7 @@ mod test {
355353
#[test]
356354
fn closes_open_node_as_empty_element() -> TestResult {
357355
let result =
358-
Token::<Ix>::SelfClose(*S).write_new(WriterState::NodeOpen)?;
356+
Token::<Ix>::Close(None, *S).write_new(WriterState::NodeOpen)?;
359357

360358
assert_eq!(result.0, b"/>");
361359
assert_eq!(result.1, WriterState::NodeExpected);
@@ -367,8 +365,8 @@ mod test {
367365
fn closing_tag_when_node_expected() -> TestResult {
368366
let name = QName::<Ix>::try_from(("a", "closed-element"))?;
369367

370-
let result =
371-
Token::Close(name, *S).write_new(WriterState::NodeExpected)?;
368+
let result = Token::Close(Some(name), *S)
369+
.write_new(WriterState::NodeExpected)?;
372370

373371
assert_eq!(result.0, b"</a:closed-element>");
374372
assert_eq!(result.1, WriterState::NodeExpected);
@@ -382,7 +380,8 @@ mod test {
382380
fn closes_open_node_with_closing_tag() -> TestResult {
383381
let name = QName::<Ix>::try_from(("b", "closed-element"))?;
384382

385-
let result = Token::Close(name, *S).write_new(WriterState::NodeOpen)?;
383+
let result =
384+
Token::Close(Some(name), *S).write_new(WriterState::NodeOpen)?;
386385

387386
assert_eq!(result.0, b"></b:closed-element>");
388387
assert_eq!(result.1, WriterState::NodeExpected);
@@ -522,8 +521,8 @@ mod test {
522521
Token::Text(Text::Escaped("text".intern()), *S),
523522
Token::Open(("c", "child").try_into()?, *S),
524523
Token::Whitespace(" ".try_into()?, *S),
525-
Token::SelfClose(*S),
526-
Token::Close(root, *S),
524+
Token::Close(None, *S),
525+
Token::Close(Some(root), *S),
527526
]
528527
.into_iter()
529528
.write_new(Default::default())?;

0 commit comments

Comments
 (0)