1 | use crate::parse::{ParseBuffer, ParseStream}; |
2 | use proc_macro2::{Delimiter, TokenStream}; |
3 | use std::cmp::Ordering; |
4 | use std::iter; |
5 | |
6 | pub fn between<'a>(begin: ParseBuffer<'a>, end: ParseStream<'a>) -> TokenStream { |
7 | let end = end.cursor(); |
8 | let mut cursor = begin.cursor(); |
9 | assert!(crate::buffer::same_buffer(end, cursor)); |
10 | |
11 | let mut tokens = TokenStream::new(); |
12 | while cursor != end { |
13 | let (tt, next) = cursor.token_tree().unwrap(); |
14 | |
15 | if crate::buffer::cmp_assuming_same_buffer(end, next) == Ordering::Less { |
16 | // A syntax node can cross the boundary of a None-delimited group |
17 | // due to such groups being transparent to the parser in most cases. |
18 | // Any time this occurs the group is known to be semantically |
19 | // irrelevant. https://github.com/dtolnay/syn/issues/1235 |
20 | if let Some((inside, _span, after)) = cursor.group(Delimiter::None) { |
21 | assert!(next == after); |
22 | cursor = inside; |
23 | continue; |
24 | } else { |
25 | panic!("verbatim end must not be inside a delimited group" ); |
26 | } |
27 | } |
28 | |
29 | tokens.extend(iter::once(tt)); |
30 | cursor = next; |
31 | } |
32 | tokens |
33 | } |
34 | |