lightning-wire-msgs-derive-base 0.2.6

derive macros for defining serialization and deserialization of lightning wire messages
Documentation
use proc_macro2::TokenStream;
use quote::quote;

pub fn impl_trait(ast: &syn::DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let data = if let syn::Data::Enum(ref data) = &ast.data {
        data
    } else {
        panic!("only derivable for enums with discriminants")
    };
    let repr = ast
        .attrs
        .iter()
        .filter_map(|attr| {
            attr.parse_meta().ok().and_then(|meta| match meta {
                syn::Meta::List(ref ml) if ml.path.is_ident("repr") => {
                    Some(ml.nested.first().expect("invalid repr").clone())
                }
                _ => None,
            })
        })
        .next()
        .expect("missing repr");
    let variant = data
        .variants
        .iter()
        .map(|var| &var.ident)
        .collect::<Vec<_>>();
    let variant_const = data
        .variants
        .iter()
        .enumerate()
        .map(|(i, var)| syn::Ident::new(&format!("C{}", i), var.ident.span()))
        .collect::<Vec<_>>();

    let gen = quote! {
        impl std::convert::TryFrom<#repr> for #name {
            type Error = #repr;

            fn try_from(prim: #repr) -> Result<Self, Self::Error> {
                #(
                    const #variant_const: #repr = #name::#variant as #repr;
                )*
                match prim {
                    #(
                        #variant_const => Ok(#name::#variant),
                    )*
                    _ => Err(prim)
                }
            }
        }
    };
    gen.into()
}