| 1 | use crate::parse::ParseStream; |
| 2 | use proc_macro2::{Delimiter, TokenStream}; |
| 3 | use std::cmp::Ordering; |
| 4 | use std::iter; |
| 5 | |
| 6 | pub(crate) fn between<'a>(begin: ParseStream<'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 | |