use proc_macro2::{TokenStream as TokenStream2, TokenTree};
use std::iter::{Peekable, once};
pub(crate) fn expect_punct(iter: &mut Peekable<impl Iterator<Item = TokenTree>>, expected: char) {
if let Some(TokenTree::Punct(punct)) = iter.next() {
if punct.as_char() != expected {
panic!("Expected '{}', found '{}'", expected, punct.as_char());
}
} else {
panic!("Expected '{}'", expected);
}
}
pub(crate) fn parse_int(iter: &mut Peekable<impl Iterator<Item = TokenTree>>) -> i128 {
let mut is_negative = false;
if let Some(TokenTree::Punct(punct)) = iter.peek() {
if punct.as_char() == '-' {
is_negative = true;
iter.next(); }
}
let value = match iter.next() {
Some(TokenTree::Literal(lit)) => {
let s = lit.to_string();
let s = s.replace('_', "");
s.parse::<i128>().expect("Invalid integer literal")
}
other => panic!("Expected integer literal, found {:?}", other),
};
if is_negative { -value } else { value }
}
pub(crate) fn parse_visibility(
iter: &mut Peekable<impl Iterator<Item = TokenTree>>,
) -> Option<TokenStream2> {
if let Some(TokenTree::Ident(ident)) = iter.peek() {
if *ident == "pub" {
let mut vis_stream = TokenStream2::new();
let Some(TokenTree::Ident(ident)) = iter.next() else { unreachable!() };
vis_stream.extend(once(TokenTree::Ident(ident.clone())));
if let Some(TokenTree::Group(group)) = iter.peek() {
if group.delimiter() == proc_macro2::Delimiter::Parenthesis {
let Some(TokenTree::Group(group)) = iter.next() else { unreachable!() };
vis_stream.extend(once(TokenTree::Group(group)));
}
}
Some(vis_stream)
} else {
None
}
} else {
None
}
}