wasm-typescript-definition 0.1.4

serde support for exporting Typescript definitions using wasm-bindgen
Documentation
use serde_derive_internals::{ast, attr};
use collapse_list_bracket;
use collapse_list_brace;
use type_to_ts;
use super::{derive_element, derive_field};
use quote::TokenStreamExt;
use proc_macro2::TokenStream;

pub fn derive_enum<'a>(
    variants: Vec<ast::Variant<'a>>,
    _attr_container: &attr::Container,
) -> TokenStream {
    let tokens = variants.into_iter().enumerate()
        .map(|(variant_idx, variant)| {
            let variant_name = variant.attrs.name().serialize_name();
            match variant.style {
                ast::Style::Struct => {
                    derive_struct_variant(&variant_name, variant_idx, &variant.fields)
                }
                ast::Style::Newtype => derive_newtype_variant(&variant_name, variant_idx, &variant.fields[0]),
                ast::Style::Tuple => derive_tuple_variant(&variant_name, variant_idx, &variant.fields),
                ast::Style::Unit => derive_unit_variant(&variant_name),
            }
        })
        .fold(quote!{}, |mut agg, tokens| { agg.append_all(tokens); agg });
    
    tokens
}

fn derive_unit_variant<'a>(variant_name: &str) -> TokenStream {
    quote!{
        | { "tag": #variant_name, }
    }
}

fn derive_newtype_variant<'a>(
    variant_name: &str, _variant_idx: usize, 
    field: &ast::Field<'a>
) -> TokenStream {
    let ty = type_to_ts(&field.ty); 
    quote!{
        | { "tag": #variant_name, "fields": #ty, }
    }
}

fn derive_struct_variant<'a>(
    variant_name: &str,
    variant_idx: usize,
    fields: &Vec<ast::Field<'a>>,
) -> TokenStream {
    let contents = collapse_list_brace(fields.into_iter().enumerate()
        .map(|(field_idx, field)| derive_field(variant_idx, field_idx, field))
        .collect::<Vec<_>>());
    quote!{
        | { "tag": #variant_name, "fields": #contents, }
    }
}

fn derive_tuple_variant<'a>(
    variant_name: &str,
    _variant_idx: usize,
    fields: &Vec<ast::Field<'a>>,
) -> TokenStream {
    let contents = collapse_list_bracket(fields.into_iter().enumerate()
        .map(|(element_idx, field)| derive_element(0, element_idx, &field))
        .collect::<Vec<_>>());
    quote!{
        | {"tag": #variant_name, "fields": #contents, }
    }
}