mod derive;
mod code_block;
use derive::*;
use proc_macro::TokenStream;
use syn::{Error, DeriveInput};
use quote::{quote, ToTokens};
use proc_macro2::{TokenTree, Spacing, TokenStream as TokenStream2};
#[proc_macro]
pub fn code_block(tokens: TokenStream) -> TokenStream {
code_block_inner(TokenStream2::from(tokens)).unwrap_or_else(|e| e.into_compile_error()).into()
}
#[allow(unused)] fn code_block_inner(tokens: TokenStream2) -> syn::Result<TokenStream2> {
let mut iter = tokens.into_iter();
let mut res: Vec<TokenStream2> = Vec::new();
while let Some(tt) = iter.next() {
match tt {
TokenTree::Ident(op) => todo!(),
TokenTree::Punct(p) if p.spacing() == Spacing::Alone => {
if let Some(TokenTree::Ident(label)) = iter.next() {
}
}
_ =>{}
}
}
todo!()
}
#[proc_macro_derive(ConstantPoolReadWrite, attributes(tag_type, tag, attr_enum, raw_variant, use_normal_rw, str_type, str_optional, vec_len_type))]
pub fn derive_cp_readwrite(item: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(item as DeriveInput);
let is_enum = input.attrs.iter().any(|a| a.path.to_token_stream().to_string() == "attr_enum");
if is_enum {
attr_enum(input)
} else {
derive_readwrite_inner(
input,
quote! { crate::ConstantPoolReadWrite },
quote! { cp,reader },
quote! { cp,writer },
quote! { <C: crate::ConstantPoolReader, R: std::io::Read>(cp: &mut C, reader: &mut R) },
quote! { <C: crate::ConstantPoolWriter, W: std::io::Write>(&self, cp: &mut C, writer: &mut W) })
}.unwrap_or_else(Error::into_compile_error).into()
}
#[proc_macro_derive(ReadWrite, attributes(tag_type, tag, vec_len_type))]
pub fn derive_readwrite(item: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(item as DeriveInput);
let res = derive_readwrite_inner(input, quote! { crate::ReadWrite }, quote! { reader }, quote! { writer }, quote! { <Reader: std::io::Read>(reader: &mut Reader) }, quote! { <Writer: std::io::Write>(&self, writer: &mut Writer) }).unwrap_or_else(Error::into_compile_error);
res.into()
}