diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index f0a9dd4a51e..4ce818f9b00 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -24,20 +24,28 @@ pub(crate) struct MetaTemplate(pub(crate) Vec<Op>); impl MetaTemplate { pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<MetaTemplate, ParseError> { - let ops = - parse_inner(pattern, Mode::Pattern).into_iter().collect::<Result<_, ParseError>>()?; - Ok(MetaTemplate(ops)) + MetaTemplate::parse(pattern, Mode::Pattern) } pub(crate) fn parse_template(template: &tt::Subtree) -> Result<MetaTemplate, ParseError> { - let ops = - parse_inner(template, Mode::Template).into_iter().collect::<Result<_, ParseError>>()?; - Ok(MetaTemplate(ops)) + MetaTemplate::parse(template, Mode::Template) } pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> { self.0.iter() } + + fn parse(tt: &tt::Subtree, mode: Mode) -> Result<MetaTemplate, ParseError> { + let mut src = TtIter::new(tt); + + let mut res = Vec::new(); + while let Some(first) = src.next() { + let op = next_op(first, &mut src, mode)?; + res.push(op) + } + + Ok(MetaTemplate(res)) + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -96,15 +104,6 @@ enum Mode { Template, } -fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ParseError>> { - let mut src = TtIter::new(tt); - std::iter::from_fn(move || { - let first = src.next()?; - Some(next_op(first, &mut src, mode)) - }) - .collect() -} - macro_rules! err { ($($tt:tt)*) => { ParseError::UnexpectedToken(($($tt)*).to_string()) @@ -128,10 +127,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul match second { tt::TokenTree::Subtree(subtree) => { let (separator, kind) = parse_repeat(src)?; - let tokens = parse_inner(subtree, mode) - .into_iter() - .collect::<Result<Vec<Op>, ParseError>>()?; - Op::Repeat { tokens: MetaTemplate(tokens), separator, kind } + let tokens = MetaTemplate::parse(subtree, mode)?; + Op::Repeat { tokens, separator, kind } } tt::TokenTree::Leaf(leaf) => match leaf { tt::Leaf::Punct(_) => { @@ -162,9 +159,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul } tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()), tt::TokenTree::Subtree(subtree) => { - let tokens = - parse_inner(subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?; - Op::Subtree { tokens: MetaTemplate(tokens), delimiter: subtree.delimiter } + let tokens = MetaTemplate::parse(subtree, mode)?; + Op::Subtree { tokens, delimiter: subtree.delimiter } } }; Ok(res)