use proc_macro::{Group, TokenStream, TokenTree};
use super::substitution_map::SubstitutionsMap;
pub(super) fn perform_substitutions(
input: TokenStream,
substitutions: &SubstitutionsMap,
) -> TokenStream {
let mut result = Vec::<TokenTree>::new();
let mut tt_iter = input.into_iter();
let mut to_skip: usize = 0;
loop {
if to_skip > 0 {
to_skip -= 1;
tt_iter.next();
continue;
}
if let Some((sub_length, sub)) = substitutions.check_subsequence(tt_iter.clone()) {
let first_token_span = tt_iter.clone().next().unwrap().span();
let final_sub = sub.clone().into_iter().map(|mut tt| {
tt.set_span(first_token_span);
tt
});
result.extend(final_sub);
to_skip = sub_length;
continue;
}
if let Some(tt) = tt_iter.next() {
match tt {
TokenTree::Group(g) => {
let mut substituted_group = TokenTree::Group(Group::new(
g.delimiter(),
perform_substitutions(g.stream(), substitutions),
));
substituted_group.set_span(g.span());
result.push(substituted_group);
continue;
},
_ => result.push(tt),
}
} else {
break;
}
}
result.into_iter().collect()
}