web_component_derive/
lib.rs

1
2extern crate proc_macro;
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{parse_macro_input, DeriveInput, Data};
6
7#[proc_macro_derive(WebComponent)]
8pub fn derive_web_component(input: TokenStream) -> TokenStream {
9    // Parse the input tokens into a syntax tree
10    let input = parse_macro_input!(input as DeriveInput);
11    let struct_name = input.ident;
12
13    let expanded = if let Data::Struct(data) = input.data {
14        let mut fields = quote!{};
15        for field in &data.fields {
16            if field.attrs.iter().find(|attribute| attribute.tokens.to_string() == "(skip)").is_none() {
17                let ident = field.ident.as_ref().expect("Unnamed field not supported.");
18                fields = quote! { #fields, #ident };
19            }
20        }
21
22        quote! {
23            impl WebComponentBinding for #struct_name {
24                fn update_field(&mut self, name: &str, value: &str) {
25                    update_field!(self, name, value #fields);
26                }
27            }
28
29            web_component!(#struct_name);
30        }
31    } else {
32        quote! {}
33    };
34
35    // Hand the output tokens back to the compiler
36    TokenStream::from(expanded)
37}