1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
extern crate proc_macro;
use proc_macro::TokenStream;

use quote::quote;
use syn::{parse_macro_input, DeriveInput};

macro_rules! derive_as_json {
  ($tr:path, $name:ident, $function:path) => {
    quote! {
      impl $tr for #$name {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
          let s = $function(&self)
            .map_err(|_| std::fmt::Error::default())?;
          write!(f, "{}", s)
        }
      }
    }
  };
}

#[proc_macro_derive(DisplayAsJson)]
pub fn derive_display_as_json(input: TokenStream) -> TokenStream {
  let input = parse_macro_input!(input as DeriveInput);
  let name = &input.ident;
  let result = derive_as_json!(
    std::fmt::Display,
    name,
    display_json::serde_json::to_string
  );
  TokenStream::from(result)
}

#[proc_macro_derive(DisplayAsJsonPretty)]
pub fn derive_display_as_json_pretty(
  input: TokenStream,
) -> TokenStream {
  let input = parse_macro_input!(input as DeriveInput);
  let name = &input.ident;
  let result = derive_as_json!(
    std::fmt::Display,
    name,
    display_json::serde_json::to_string_pretty
  );
  TokenStream::from(result)
}

#[proc_macro_derive(DebugAsJson)]
pub fn derive_debug_as_json(input: TokenStream) -> TokenStream {
  let input = parse_macro_input!(input as DeriveInput);
  let name = &input.ident;
  let result = derive_as_json!(
    std::fmt::Debug,
    name,
    display_json::serde_json::to_string
  );
  TokenStream::from(result)
}

#[proc_macro_derive(DebugAsJsonPretty)]
pub fn derive_debug_as_json_pretty(
  input: TokenStream,
) -> TokenStream {
  let input = parse_macro_input!(input as DeriveInput);
  let name = &input.ident;
  let result = derive_as_json!(
    std::fmt::Debug,
    name,
    display_json::serde_json::to_string_pretty
  );
  TokenStream::from(result)
}