1extern crate proc_macro;
2
3use convert_case::{Boundary, Case, Casing};
4use proc_macro::TokenStream;
5use quote::quote;
6use syn::DeriveInput;
7
8#[proc_macro_derive(DeExchange)]
9pub fn de_exchange_derive(input: TokenStream) -> TokenStream {
10 let ast: DeriveInput =
12 syn::parse(input).expect("de_exchange_derive() failed to parse input TokenStream");
13
14 let exchange = &ast.ident;
16
17 let generated = quote! {
18 impl<'de> serde::Deserialize<'de> for #exchange {
19 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
20 where
21 D: serde::de::Deserializer<'de>
22 {
23 let input = <String as serde::Deserialize>::deserialize(deserializer)?;
24 let exchange = #exchange::ID;
25 let expected = exchange.as_str();
26
27 if input.as_str() == expected {
28 Ok(Self::default())
29 } else {
30 Err(serde::de::Error::invalid_value(
31 serde::de::Unexpected::Str(input.as_str()),
32 &expected
33 ))
34 }
35 }
36 }
37 };
38
39 TokenStream::from(generated)
40}
41
42#[proc_macro_derive(SerExchange)]
43pub fn ser_exchange_derive(input: TokenStream) -> TokenStream {
44 let ast: DeriveInput =
46 syn::parse(input).expect("ser_exchange_derive() failed to parse input TokenStream");
47
48 let exchange = &ast.ident;
50
51 let generated = quote! {
52 impl serde::Serialize for #exchange {
53 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
54 where
55 S: serde::ser::Serializer,
56 {
57 serializer.serialize_str(#exchange::ID.as_str())
58 }
59 }
60 };
61
62 TokenStream::from(generated)
63}
64
65#[proc_macro_derive(DeSubKind)]
66pub fn de_sub_kind_derive(input: TokenStream) -> TokenStream {
67 let ast: DeriveInput =
69 syn::parse(input).expect("de_sub_kind_derive() failed to parse input TokenStream");
70
71 let sub_kind = &ast.ident;
73
74 let expected_sub_kind = sub_kind
75 .to_string()
76 .from_case(Case::Pascal)
77 .without_boundaries(&Boundary::letter_digit())
78 .to_case(Case::Snake);
79
80 let generated = quote! {
81 impl<'de> serde::Deserialize<'de> for #sub_kind {
82 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83 where
84 D: serde::de::Deserializer<'de>
85 {
86 let input = <String as serde::Deserialize>::deserialize(deserializer)?;
87
88 if input == #expected_sub_kind {
89 Ok(Self)
90 } else {
91 Err(serde::de::Error::invalid_value(
92 serde::de::Unexpected::Str(input.as_str()),
93 &#expected_sub_kind
94 ))
95 }
96 }
97 }
98 };
99
100 TokenStream::from(generated)
101}
102
103#[proc_macro_derive(SerSubKind)]
104pub fn ser_sub_kind_derive(input: TokenStream) -> TokenStream {
105 let ast: DeriveInput =
107 syn::parse(input).expect("ser_sub_kind_derive() failed to parse input TokenStream");
108
109 let sub_kind = &ast.ident;
111 let sub_kind_string = sub_kind.to_string().to_case(Case::Snake);
112 let sub_kind_str = sub_kind_string.as_str();
113
114 let generated = quote! {
115 impl serde::Serialize for #sub_kind {
116 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
117 where
118 S: serde::ser::Serializer,
119 {
120 serializer.serialize_str(#sub_kind_str)
121 }
122 }
123 };
124
125 TokenStream::from(generated)
126}