use proc_macro::{Delimiter, TokenStream, TokenTree}; use quote::quote; struct Tag { id: u64, path: Vec, name: String, r#type: Option, // None -> Master } #[proc_macro] pub fn define_ebml(ts: TokenStream) -> TokenStream { let mut next_glob = false; let mut ts = ts.into_iter(); let mut tags = vec![]; while let Some(t) = ts.next() { match t { TokenTree::Ident(ident) => { let ident = ident.to_string(); if &ident == "global" { next_glob = true; } else { let glob = next_glob; next_glob = false; let id = if let Some(TokenTree::Group(gr)) = ts.next() { assert_eq!(gr.delimiter(), Delimiter::Bracket); let mut ts = gr.stream().into_iter(); if let TokenTree::Literal(lit) = ts.next().unwrap() { u64::from_str_radix(&lit.to_string()[2..], 16).unwrap() } else { panic!("literal expected") } } else { panic!("group expected") }; if let Some(TokenTree::Punct(p)) = ts.next() { assert_eq!(p.as_char(), ':') } else { panic!("colon expected") } match ts.next() { Some(TokenTree::Group(_)) => {} Some(TokenTree::Ident(ident)) => { let r#type = ident.to_string(); eprintln!("global={glob} id={id}, type={}", r#type); } _ => panic!("group or ident expected"), } if let Some(TokenTree::Punct(p)) = ts.next() { assert_eq!(p.as_char(), ',') } else { panic!("colon expected") } } } x => panic!("unexpected {x:?}"), } } quote! {}.into() }