json_derive/
lib.rs

1#![recursion_limit = "128"]
2#![cfg_attr(tarpaulin, skip)]
3#![warn(unused_extern_crates)]
4
5extern crate proc_macro;
6use syn;
7#[macro_use]
8extern crate quote;
9
10use proc_macro::TokenStream;
11fn impl_default_json_macro(ast: &syn::DeriveInput) -> TokenStream {
12    let name = &ast.ident;
13    let gen = quote! {
14
15        impl<'a> From<&'a #name> for JsonString {
16            fn from(v: &#name) -> JsonString {
17                match ::serde_json::to_string(v) {
18                    Ok(s) => Ok(JsonString::from_json(&s)),
19                    Err(e) => {
20                        eprintln!("Error serializing to JSON: {:?}", e);
21                        Err(JsonError::SerializationError(e.to_string()))
22                    },
23                }.expect(&format!("could not Jsonify {}: {:?}", stringify!(#name), v))
24            }
25        }
26
27        impl From<#name> for JsonString {
28            fn from(v: #name) -> JsonString {
29                JsonString::from(&v)
30            }
31        }
32
33        impl<'a> ::std::convert::TryFrom<&'a JsonString> for #name {
34            type Error = JsonError;
35            fn try_from(json_string: &JsonString) -> Result<Self, Self::Error> {
36                match ::serde_json::from_str(&String::from(json_string)) {
37                    Ok(d) => Ok(d),
38                    Err(e) => Err(JsonError::SerializationError(e.to_string())),
39                }
40            }
41        }
42
43        impl ::std::convert::TryFrom<JsonString> for #name {
44            type Error = JsonError;
45            fn try_from(json_string: JsonString) -> Result<Self, Self::Error> {
46                #name::try_from(&json_string)
47            }
48        }
49    };
50    gen.into()
51}
52
53#[proc_macro_derive(DefaultJson)]
54pub fn default_json_derive(input: TokenStream) -> TokenStream {
55    // Construct a represntation of Rust code as a syntax tree
56    // that we can manipulate
57    let ast = syn::parse(input).unwrap();
58
59    // Build the trait implementation
60    impl_default_json_macro(&ast)
61}