blob: 78be0a960a3e47e23ac2c037cf96afc5f5138d33 [file] [log] [blame]
use proc_macro::*;
use std::iter::FromIterator;
use crate::Result;
macro_rules! error {
($span:expr, $msg:expr) => {{
crate::error::Error::new($span, $msg)
}};
($span:expr, $($tt:tt)*) => {
error!($span, format!($($tt)*))
};
}
pub(crate) fn tt_span(tt: Option<&TokenTree>) -> Span {
tt.map_or_else(Span::call_site, TokenTree::span)
}
pub(crate) fn parse_as_empty(mut tokens: impl Iterator<Item = TokenTree>) -> Result<()> {
match tokens.next() {
Some(tt) => Err(error!(tt.span(), "unexpected token: {}", tt)),
None => Ok(()),
}
}
// (`#[cfg(<tokens>)]`, `#[cfg(not(<tokens>))]`)
pub(crate) fn cfg_attrs(tokens: TokenStream) -> (TokenStream, TokenStream) {
let f = |tokens| {
let tokens = TokenStream::from_iter(vec![
TokenTree::Ident(Ident::new("cfg", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Parenthesis, tokens)),
]);
TokenStream::from_iter(vec![
TokenTree::Punct(Punct::new('#', Spacing::Alone)),
TokenTree::Group(Group::new(Delimiter::Bracket, tokens)),
])
};
let cfg_not = TokenTree::Group(Group::new(Delimiter::Parenthesis, tokens.clone()));
let cfg_not = TokenStream::from_iter(vec![
TokenTree::Ident(Ident::new("not", Span::call_site())),
cfg_not,
]);
(f(tokens), f(cfg_not))
}