tamer: xir::tree: Remove isolated AttrList parsing

This isn't currently used by anything, and this is collecting, which does
not fit well with the streaming model.  AttrList was originally written for
Element parsing, and the isolated attr parser was written for test cases,
before it was fully decided how this system ought to work.

Instead, if AttrList is in fact needed, we can either collect (ideally not)
or implement Extend for AttrList.  (Or create TryExtend.)

DEV-11268
main
Mike Gerwitz 2021-12-13 16:20:50 -05:00
parent 29fdf5428c
commit f09900b80c
2 changed files with 3 additions and 131 deletions

View File

@ -82,8 +82,8 @@
//! and the [`Iterator`] produced by [`parser_from`] will cause the
//! system to process [`Iterator::next`] for that entire duration.
//!
//! See also [`attr_parser_from`] and [`parse_attrs`] for parsing only
//! attributes partway through a token stream.
//! See also [`attr_parser_from`] for parsing only attributes partway
//! through a token stream.
//!
//! [`Parsed::Incomplete`]: parse::Parsed::Incomplete
//! [`Parsed::Object`]: parse::Parsed::Object
@ -492,9 +492,6 @@ pub enum Stack {
/// after which it will be attached to an element.
AttrName(Option<(Option<ElementStack>, AttrList)>, QName, Span),
/// A completed [`AttrList`] without any [`Element`] context.
IsolatedAttrList(AttrList),
/// A completed [`Attr`] without any [`AttrList`] context.
IsolatedAttr(Attr),
@ -678,10 +675,6 @@ impl Stack {
/// [`Element`].
fn end_attrs(self) -> Result<Self> {
Ok(match self {
Self::BuddingAttrList(None, attr_list) => {
Self::IsolatedAttrList(attr_list)
}
Self::BuddingAttrList(Some(ele_stack), attr_list) => {
Self::BuddingElement(ele_stack.consume_attrs(attr_list))
}
@ -712,9 +705,6 @@ impl Stack {
Stack::ClosedElement(ele) => {
ParseStatus::Object(Object::Tree(Tree::Element(ele)))
}
Stack::IsolatedAttrList(attr_list) => {
ParseStatus::Object(Object::AttrList(attr_list))
}
Stack::IsolatedAttr(attr) => {
*self = Stack::IsolatedAttrEmpty;
@ -841,11 +831,6 @@ pub enum Object {
/// See [`parser_from`].
Tree(Tree),
/// Parsing of an isolated attribute list is complete.
///
/// See [`parse_attrs`].
AttrList(AttrList),
/// Parsing of a single isolated attribute is complete.
///
/// See [`attr_parser_from`].
@ -911,7 +896,7 @@ pub fn parser_from(
Err(x) => Some(Err(x)),
// These make no sense in this context and should never occur.
Ok(x @ Parsed::Object(Object::AttrList(_) | Object::Attr(_))) => {
Ok(x @ Parsed::Object(Object::Attr(_))) => {
unreachable!(
"unexpected yield by XIRT (Tree expected): {:?}",
x
@ -920,46 +905,6 @@ pub fn parser_from(
})
}
/// Begin parsing in an isolated attribute context,
/// producing an [`AttrList`] that is detached from any [`Element`].
///
/// This is useful when you wish to consume a XIR stream and collect only
/// the attributes of an element.
/// If you wish to process an entire element,
/// use [`parser_from`] instead.
///
/// Parsing must begin at a [`Token::AttrName`] token.
///
/// This will consume tokens until reaching [`Token::AttrEnd`],
/// and so it is important that the XIR stream contain this delimiter;
/// this should be the case with all readers.
#[inline]
pub fn parse_attrs<'a>(
toks: &mut impl TokenStream,
dest: AttrList,
) -> Result<AttrList> {
let mut state = Stack::BuddingAttrList(None, dest);
loop {
match toks.next().and_then(|tok| parse(&mut state, tok)) {
None => return Err(StackError::UnexpectedAttrEof),
Some(Err(err)) => return Err(err),
Some(Ok(Parsed::Incomplete)) => continue,
Some(Ok(Parsed::Object(Object::AttrList(attr_list)))) => {
return Ok(attr_list)
}
// These make no sense in this context and should never occur.
Some(Ok(x @ Parsed::Object(Object::Tree(_) | Object::Attr(_)))) => {
unreachable!(
"unexpected yield by XIRT (AttrList expected): {:?}",
x
)
}
}
}
}
/// Produce a lazy attribute parser from a given [`TokenStream`],
/// yielding only when an attribute has been fully parsed.
///

View File

@ -382,79 +382,6 @@ fn parser_from_filters_incomplete() {
assert_eq!(sut.next(), None);
}
#[test]
fn parse_attrs_fails_if_first_token_is_non_attr() {
let tok = Token::Open("foo".unwrap_into(), *S);
let mut toks = [tok.clone()].into_iter();
assert_eq!(
Err(StackError::AttrNameExpected(tok)),
parse_attrs(&mut toks, AttrList::new()),
);
// The token should have been consumed, not copied.
assert_eq!(0, toks.len());
}
// Since the purpose of this function is to parse the complete attribute
// list, it must fail if it does not encounter `AttrEnd`.
#[test]
fn parse_attrs_fails_if_end_before_attr_end() {
let mut toks = [
Token::AttrName("foo".unwrap_into(), *S),
Token::AttrValue("bar".intern(), *S),
// No Token::AttrEnd
]
.into_iter();
assert_eq!(
Err(StackError::UnexpectedAttrEof),
parse_attrs(&mut toks, AttrList::new()),
);
}
#[test]
fn parse_attrs_fails_if_missing_attr_end() {
// Let's also ensure we fail if some other token is available in place
// of Token::AttrEnd.
let mut toks = [
Token::AttrName("foo".unwrap_into(), *S),
Token::AttrValue("bar".intern(), *S2),
// No Token::AttrEnd
Token::Close(None, *S3),
]
.into_iter();
assert_eq!(
Err(StackError::MissingIsolatedAttrEnd(*S3)),
parse_attrs(&mut toks, AttrList::new()),
);
}
#[test]
fn parse_attrs_isolated() {
let attr1 = "one".unwrap_into();
let attr2 = "two".unwrap_into();
let val1 = "val1".intern();
let val2 = "val2".intern();
let mut toks = [
Token::AttrName(attr1, *S),
Token::AttrValue(val1, *S2),
Token::AttrName(attr2, *S2),
Token::AttrValue(val2, *S3),
Token::AttrEnd(*S3),
]
.into_iter();
let expected = AttrList::from([
Attr::new(attr1, val1, (*S, *S2)),
Attr::new(attr2, val2, (*S2, *S3)),
]);
assert_eq!(expected, parse_attrs(&mut toks, AttrList::new()).unwrap());
}
#[test]
fn attr_parser_with_non_attr_token() {
let name = "unexpected".unwrap_into();