use proc_macro2::{Ident, Spacing, TokenTree};
pub(crate) fn try_parse_path_prefix(
tokens: &[TokenTree],
) -> Option<(Vec<TokenTree>, Option<Ident>, Vec<TokenTree>)> {
if tokens.len() < 5 {
return None;
}
if !matches!(&tokens[0], TokenTree::Punct(p) if p.as_char() == '#') {
return None;
}
if !matches!(&tokens[1], TokenTree::Ident(_)) {
return None;
}
let mut i = 2usize;
let mut expect_sep = true;
let mut saw_double_colon = false;
let mut last_ident: Option<Ident> = None;
loop {
match tokens.get(i) {
Some(TokenTree::Punct(p))
if p.as_char() == ':' && expect_sep =>
{
match tokens.get(i + 1) {
Some(TokenTree::Punct(p2))
if p2.as_char() == ':'
&& p.spacing() == Spacing::Joint =>
{
i += 2;
expect_sep = false;
saw_double_colon = true;
},
_ if saw_double_colon => {
let path = tokens[1..i].to_vec();
let rest = tokens[i + 1..].to_vec();
return Some((path, last_ident, rest));
},
_ => return None,
}
},
Some(TokenTree::Ident(id)) if !expect_sep => {
i += 1;
last_ident = Some(id.clone());
expect_sep = true;
},
_ => return None,
}
}
}