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