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}