postchain-client-derive 0.0.1

Chromia Postchain client derive.
Documentation
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Data, Fields};

#[proc_macro_derive(StructMetadata)]
pub fn derive_struct_metadata(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;

    let fields = if let Data::Struct(data_struct) = &input.data {
        if let Fields::Named(fields_named) = &data_struct.fields {
            &fields_named.named
        } else {
            panic!("StructMetadata can only be derived for structs with named fields");
        }
    } else {
        panic!("StructMetadata can only be derived for structs");
    };

    let field_collector = fields.iter().map(|field| {
        let field_name = &field.ident;
        let field_type = &field.ty;
        quote! {
            fields.insert(stringify!(#field_name).to_string(), stringify!(#field_type).to_string());
        }
    });

    let expanded = quote! {
        impl StructMetadata for #name {
            fn field_names_and_types() -> std::collections::BTreeMap<String, String> {
                let mut fields = std::collections::BTreeMap::new();
                #(#field_collector)*
                fields
            }
        }
    };

    TokenStream::from(expanded)
}