memorix_client_redis_macros/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput, Fields, Type};
4
5#[proc_macro_attribute]
6pub fn serialization(_attr: TokenStream, item: TokenStream) -> TokenStream {
7 let mut input = parse_macro_input!(item as DeriveInput);
8
9 if let Data::Struct(ref mut data) = input.data {
10 if let Fields::Named(ref mut fields) = data.fields {
11 for field in fields.named.iter_mut() {
12 if is_option(&field.ty) {
13 field
14 .attrs
15 .push(syn::parse_quote!(#[serde(skip_serializing_if = "Option::is_none")]));
16 }
17 }
18 }
19 }
20
21 let name = &input.ident;
22 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
23
24 let expanded = quote! {
25 #[derive(::memorix_client_redis::__private::serde::Serialize, ::memorix_client_redis::__private::serde::Deserialize)]
26 #[serde(crate = "::memorix_client_redis::__private::serde")]
27 #input
28
29 impl #impl_generics #name #ty_generics #where_clause {
30 pub fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31 where
32 S: ::memorix_client_redis::__private::serde::Serializer,
33 {
34 ::memorix_client_redis::__private::serde::Serialize::serialize(self, serializer)
35 }
36
37 pub fn deserialize<'de, D>(deserializer: D) -> Result<Self, D::Error>
38 where
39 D: ::memorix_client_redis::__private::serde::Deserializer<'de>,
40 {
41 ::memorix_client_redis::__private::serde::Deserialize::deserialize(deserializer)
42 }
43 }
44 };
45
46 TokenStream::from(expanded)
47}
48
49fn is_option(ty: &Type) -> bool {
50 if let Type::Path(type_path) = ty {
51 if let Some(segment) = type_path.path.segments.last() {
52 return segment.ident == "Option";
53 }
54 }
55 false
56}