extern crate proc_macro;
use convert_case::{Boundary, Case, Casing};
use proc_macro::TokenStream;
use quote::quote;
use syn::DeriveInput;
#[proc_macro_derive(DeExchange)]
pub fn de_exchange_derive(input: TokenStream) -> TokenStream {
let ast: DeriveInput =
syn::parse(input).expect("de_exchange_derive() failed to parse input TokenStream");
let exchange = &ast.ident;
let generated = quote! {
impl<'de> serde::Deserialize<'de> for #exchange {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>
{
let input = <String as serde::Deserialize>::deserialize(deserializer)?;
let expected = #exchange::ID.as_str();
if input.as_str() == expected {
Ok(Self::default())
} else {
Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(input.as_str()),
&expected
))
}
}
}
};
TokenStream::from(generated)
}
#[proc_macro_derive(SerExchange)]
pub fn ser_exchange_derive(input: TokenStream) -> TokenStream {
let ast: DeriveInput =
syn::parse(input).expect("ser_exchange_derive() failed to parse input TokenStream");
let exchange = &ast.ident;
let generated = quote! {
impl serde::Serialize for #exchange {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
let exchange_id = #exchange::ID.as_str();
serializer.serialize_str(exchange_id)
}
}
};
TokenStream::from(generated)
}
#[proc_macro_derive(DeSubKind)]
pub fn de_sub_kind_derive(input: TokenStream) -> TokenStream {
let ast: DeriveInput =
syn::parse(input).expect("de_sub_kind_derive() failed to parse input TokenStream");
let sub_kind = &ast.ident;
let expected_sub_kind = sub_kind
.to_string()
.from_case(Case::Pascal)
.without_boundaries(&Boundary::letter_digit())
.to_case(Case::Snake);
let generated = quote! {
impl<'de> serde::Deserialize<'de> for #sub_kind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>
{
let input = <String as serde::Deserialize>::deserialize(deserializer)?;
if input == #expected_sub_kind {
Ok(Self)
} else {
Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(input.as_str()),
&#expected_sub_kind
))
}
}
}
};
TokenStream::from(generated)
}
#[proc_macro_derive(SerSubKind)]
pub fn ser_sub_kind_derive(input: TokenStream) -> TokenStream {
let ast: DeriveInput =
syn::parse(input).expect("ser_sub_kind_derive() failed to parse input TokenStream");
let sub_kind = &ast.ident;
let sub_kind_string = sub_kind.to_string().to_case(Case::Snake);
let sub_kind_str = sub_kind_string.as_str();
let generated = quote! {
impl serde::Serialize for #sub_kind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(#sub_kind_str)
}
}
};
TokenStream::from(generated)
}