holochain_json_derive/
lib.rs

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