brackets_macros/
lib.rs

1#[macro_use]
2extern crate quote;
3extern crate proc_macro;
4
5use proc_macro::TokenStream;
6use quote::{format_ident, ToTokens};
7use syn::{parse_macro_input, ItemStruct};
8
9#[proc_macro_derive(ToJson)]
10pub fn derive_to_json(item: TokenStream) -> TokenStream {
11    let struct_ident = parse_macro_input!(item as ItemStruct);
12    let struct_name = struct_ident.ident;
13    let struct_fields = struct_ident.fields.iter().map(|x| {
14        let x_ident = &x.ident;
15        let x_key = x.ident.to_token_stream().to_string();
16        quote! {
17            output += "\"";
18            output += #x_key;
19            output += "\" : ";
20            output += &self.#x_ident.to_json();
21            output += ",";
22        }
23    });
24    let generics = struct_ident.generics;
25    let impl_types = generics.params.iter().map(|x| {
26        let d = format_ident!("{}", x.to_token_stream().to_string().split(':').next().unwrap().trim());
27        quote! {#d}
28    }).collect::<Vec<_>>();
29    let impl_insert = if impl_types.is_empty() { quote!{} } else {quote!{<#(#impl_types),*>}};
30
31    let output_new = quote! {
32        impl #generics brackets::ToJson for #struct_name #impl_insert {
33            fn to_json(&self) -> String {
34                let mut output = String::new();
35                output += "{";
36                #(#struct_fields)*
37                output.pop();
38                output += "}";
39                return output;
40            }
41        }
42    };
43
44    output_new.into()
45}
46
47#[proc_macro_derive(FromJson)]
48pub fn derive_from_json(item: TokenStream) -> TokenStream {
49    let strct = parse_macro_input!(item as ItemStruct);
50    let struct_name = &strct.ident;
51
52    let fields_get = strct.fields.iter().map(|x| {
53        let x_ident = &x.ident;
54        let x_key = x.ident.to_token_stream().to_string();
55        quote! {
56            #x_ident: json.get(#x_key)?
57        }
58    });
59
60    quote! {
61        impl brackets::FromJson for #struct_name {
62            fn from_json(json: &brackets::JsonObject) -> Result<#struct_name, brackets::JsonParseError> {
63                Ok(#struct_name {
64                    #(#fields_get),*
65                })
66            }
67        }
68    }.into()
69}