// SPDX-License-Identifier: GPL-2.0
-use proc_macro2::{token_stream, Ident, TokenStream, TokenTree};
+use proc_macro2::{
+ Ident,
+ TokenStream,
+ TokenTree, //
+};
+use syn::{
+ parse::{
+ Parse,
+ ParseStream, //
+ },
+ Result,
+ Token, //
+};
-use crate::helpers::expect_punct;
+pub(crate) struct Input {
+ a: Ident,
+ _comma: Token![,],
+ b: Ident,
+}
-fn expect_ident(it: &mut token_stream::IntoIter) -> Ident {
- if let Some(TokenTree::Ident(ident)) = it.next() {
- ident
- } else {
- panic!("Expected Ident")
+impl Parse for Input {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ Ok(Self {
+ a: input.parse()?,
+ _comma: input.parse()?,
+ b: input.parse()?,
+ })
}
}
-pub(crate) fn concat_idents(ts: TokenStream) -> TokenStream {
- let mut it = ts.into_iter();
- let a = expect_ident(&mut it);
- assert_eq!(expect_punct(&mut it), ',');
- let b = expect_ident(&mut it);
- assert!(it.next().is_none(), "only two idents can be concatenated");
+pub(crate) fn concat_idents(Input { a, b, .. }: Input) -> TokenStream {
let res = Ident::new(&format!("{a}{b}"), b.span());
TokenStream::from_iter([TokenTree::Ident(res)])
}
// SPDX-License-Identifier: GPL-2.0
-use proc_macro2::{
- token_stream,
- TokenStream,
- TokenTree, //
-};
+use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::{
parse::{
Result, //
};
-pub(crate) fn expect_punct(it: &mut token_stream::IntoIter) -> char {
- if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
- punct.as_char()
- } else {
- panic!("Expected Punct");
- }
-}
-
/// A string literal that is required to have ASCII value only.
pub(crate) struct AsciiLitStr(LitStr);
/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
/// ```
#[proc_macro]
-pub fn concat_idents(ts: TokenStream) -> TokenStream {
- concat_idents::concat_idents(ts.into()).into()
+pub fn concat_idents(input: TokenStream) -> TokenStream {
+ concat_idents::concat_idents(parse_macro_input!(input)).into()
}
/// Paste identifiers together.