1use crate::parse_utils::TokenTreeExt;
2
3use proc_macro2::{Delimiter, Span, TokenStream as TokenStream2, TokenTree as TokenTree2};
4
5const MSG: &str = "Expected the macro to be called as `respan_to!((tokens) more tokens)`";
6
7fn parse_paren(tt: TokenTree2) -> TokenStream2 {
8 match tt {
9 TokenTree2::Group(group: Group) if group.delimiter() == Delimiter::Parenthesis => group.stream(),
10 _ => panic!("{}", MSG),
11 }
12}
13
14fn get_span(ts: TokenStream2) -> Span {
15 let mut iter: IntoIter = ts.into_iter();
16
17 match iter.next() {
18 Some(TokenTree2::Group(group: Group)) if group.delimiter() == Delimiter::None => {
19 get_span(ts:group.stream())
20 }
21 Some(first_tt: TokenTree) => {
22 let mut span: Span = first_tt.span();
23
24 for tt: TokenTree in iter {
25 span = span.join(tt.span()).unwrap_or(default:span);
26 }
27 span
28 }
29 None => Span::mixed_site(),
30 }
31}
32
33pub(crate) fn implementation(ts: TokenStream2) -> TokenStream2 {
34 let mut iter: IntoIter = ts.into_iter();
35
36 let span_to: Span = get_span(ts:parse_paren(tt:iter.next().expect(MSG)));
37
38 iter.map(|tt: TokenTree| tt.set_span_recursive(span_to)).collect()
39}
40