const_fn/
utils.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use std::iter::FromIterator;
4
5use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
6
7use crate::{iter::TokenIter, Result};
8
9pub(crate) fn tt_span(tt: Option<&TokenTree>) -> Span {
10    tt.map_or_else(Span::call_site, TokenTree::span)
11}
12
13pub(crate) fn parse_as_empty(tokens: &mut TokenIter) -> Result<()> {
14    match tokens.next() {
15        Some(tt) => bail!(tt.span(), "unexpected token: `{}`", tt),
16        None => Ok(()),
17    }
18}
19
20// (`#[cfg(<tokens>)]`, `#[cfg(not(<tokens>))]`)
21pub(crate) fn cfg_attrs(tokens: TokenStream) -> (TokenStream, TokenStream) {
22    let f = |tokens| {
23        let tokens = TokenStream::from_iter(vec![
24            TokenTree::Ident(Ident::new("cfg", Span::call_site())),
25            TokenTree::Group(Group::new(Delimiter::Parenthesis, tokens)),
26        ]);
27        TokenStream::from_iter(vec![
28            TokenTree::Punct(Punct::new('#', Spacing::Alone)),
29            TokenTree::Group(Group::new(Delimiter::Bracket, tokens)),
30        ])
31    };
32
33    let cfg_not = TokenTree::Group(Group::new(Delimiter::Parenthesis, tokens.clone()));
34    let cfg_not = TokenStream::from_iter(vec![
35        TokenTree::Ident(Ident::new("not", Span::call_site())),
36        cfg_not,
37    ]);
38
39    (f(tokens), f(cfg_not))
40}