1use proc_macro::TokenStream;
5use quote::quote;
6use syn::{
7 parse_macro_input, Data, DataEnum, DataStruct, DeriveInput, Fields, Lifetime, LifetimeParam,
8};
9
10#[proc_macro_derive(Serialize)]
15pub fn derse_serialize_derive(input: TokenStream) -> TokenStream {
16 let ast = parse_macro_input!(input as DeriveInput);
17 let krate = get_crate_name();
18 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
19
20 let struct_type = &ast.ident;
21 let statements = match ast.data {
22 Data::Struct(DataStruct { fields, .. }) => {
23 let mut idents = fields
24 .iter()
25 .enumerate()
26 .map(|(i, f)| {
27 let index = syn::Index::from(i);
28 f.ident
29 .as_ref()
30 .map_or(quote! {#index}, |ident| quote! {#ident})
31 })
32 .collect::<Vec<_>>();
33 idents.reverse();
34 quote! { #( self.#idents.serialize_to(serializer)?; )* }
35 }
36 Data::Enum(DataEnum { variants, .. }) => {
37 let mut match_statements = Vec::new();
38 for variant in variants {
39 let ident = &variant.ident;
40 let name = ident.to_string();
41 let match_statement = match variant.fields {
42 Fields::Named(fields) => {
43 let mut idents = fields.named.iter().map(|f| &f.ident).collect::<Vec<_>>();
44 let list = quote! { #(#idents, )* };
45 idents.reverse();
46 quote! {
47 Self::#ident { #list } => {
48 #( #idents.serialize_to(serializer)?; )*
49 #name.serialize_to(serializer)?;
50 }
51 }
52 }
53 Fields::Unnamed(fields) => {
54 let mut idents = fields
55 .unnamed
56 .iter()
57 .enumerate()
58 .map(|(i, _)| {
59 syn::Ident::new(&format!("v{i}"), proc_macro2::Span::call_site())
60 })
61 .collect::<Vec<_>>();
62 let list = quote! { #(#idents, )* };
63 idents.reverse();
64 quote! {
65 Self::#ident ( #list ) => {
66 #( #idents.serialize_to(serializer)?; )*
67 #name.serialize_to(serializer)?;
68 }
69 }
70 }
71 Fields::Unit => quote! {
72 Self::#ident => {
73 #name.serialize_to(serializer)?;
74 }
75 },
76 };
77 match_statements.push(match_statement);
78 }
79 quote! {
80 match self {
81 #(#match_statements)*
82 }
83 }
84 }
85 _ => panic!("only struct and enum are supported"),
86 };
87
88 quote! {
89 impl #impl_generics #krate::Serialize for #struct_type #ty_generics #where_clause {
90 fn serialize_to<Serializer: #krate::Serializer>(&self, serializer: &mut Serializer) -> #krate::Result<()> {
91 let start = serializer.len();
92 #statements
93 let len = serializer.len() - start;
94 #krate::VarInt64(len as u64).serialize_to(serializer)
95 }
96 }
97 }.into()
98}
99
100#[proc_macro_derive(Deserialize)]
105pub fn derse_deserialize_derive(input: TokenStream) -> TokenStream {
106 let ast = parse_macro_input!(input as DeriveInput);
107 let krate = get_crate_name();
108
109 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
110 let mut generics = ast.generics.clone();
111 let (impl_generics, lifetime) = if let Some(lifetime) = ast.generics.lifetimes().next().cloned()
112 {
113 (impl_generics, quote! { #lifetime })
114 } else {
115 let lifetime = Lifetime::new("'derse", proc_macro2::Span::call_site());
116 let lifetime_param = LifetimeParam::new(lifetime.clone());
117 let generic_param = syn::GenericParam::Lifetime(lifetime_param);
118 generics.params.insert(0, generic_param);
119 let (impl_generics, _, _) = generics.split_for_impl();
120 (impl_generics, quote! { #lifetime })
121 };
122
123 let struct_type = &ast.ident;
124 let struct_name = struct_type.to_string();
125 let deserialize_statements = match ast.data {
126 Data::Struct(DataStruct { fields, .. }) => {
127 let statements = fields
128 .iter()
129 .map(|f| {
130 let statement = quote! {
131 if buf.is_empty() {
132 Default::default()
133 } else {
134 derse::Deserialize::deserialize_from(buf)?
135 }
136 };
137 f.ident
138 .as_ref()
139 .map_or(statement.clone(), |ident| quote! {#ident: #statement})
140 })
141 .collect::<Vec<_>>();
142 match fields {
143 Fields::Named(_) => quote! { let result = Self { #(#statements, )* }; },
144 Fields::Unnamed(_) => quote! { let result = Self ( #(#statements, )* ); },
145 Fields::Unit => quote! { let result = Self; },
146 }
147 }
148 Data::Enum(DataEnum { variants, .. }) => {
149 let mut match_statements = Vec::new();
150 for variant in variants {
151 let ident = &variant.ident;
152 let variant_name = ident.to_string();
153 let statements = variant
154 .fields
155 .iter()
156 .map(|f| {
157 let statement = quote! {
158 if buf.is_empty() {
159 Default::default()
160 } else {
161 derse::Deserialize::deserialize_from(buf)?
162 }
163 };
164 f.ident
165 .as_ref()
166 .map_or(statement.clone(), |ident| quote! {#ident: #statement})
167 })
168 .collect::<Vec<_>>();
169 let match_statement = match variant.fields {
170 Fields::Named(_) => {
171 quote! { #variant_name => Self::#ident { #(#statements, )* }, }
172 }
173 Fields::Unnamed(_) => {
174 quote! { #variant_name => Self::#ident ( #(#statements, )* ), }
175 }
176 Fields::Unit => quote! { #variant_name => Self::#ident, },
177 };
178 match_statements.push(match_statement);
179 }
180 quote! {
181 let ty = <&str>::deserialize_from(buf)?;
182 let result = match ty {
183 #(#match_statements)*
184 _ => return Err(derse::Error::InvalidType(format!("{}::{}", #struct_name, ty))),
185 };
186 }
187 }
188 _ => panic!("only struct and enum are supported"),
189 };
190
191 quote! {
192 impl #impl_generics #krate::DetailedDeserialize<#lifetime> for #struct_type #ty_generics #where_clause {
193 fn deserialize_len<Deserializer: #krate::Deserializer<#lifetime>>(buf: &mut Deserializer) -> #krate::Result<usize> {
194 use #krate::Deserialize;
195 Ok(#krate::VarInt64::deserialize_from(buf)?.0 as usize)
196 }
197
198 fn deserialize_fields<Deserializer: #krate::Deserializer<#lifetime>>(buf: &mut Deserializer) -> #krate::Result<Self>
199 where
200 Self: Sized,
201 {
202 use #krate::Deserialize;
203 #deserialize_statements
204 Ok(result)
205 }
206 }
207
208 impl #impl_generics #krate::Deserialize<#lifetime> for #struct_type #ty_generics #where_clause {
209 fn deserialize_from<Deserializer: #krate::Deserializer<#lifetime>>(buf: &mut Deserializer) -> #krate::Result<Self>
210 where
211 Self: Sized,
212 {
213 use #krate::DetailedDeserialize;
214 let len = Self::deserialize_len(buf)?;
215 let mut buf = buf.advance(len)?;
216 Self::deserialize_fields(&mut buf)
217 }
218 }
219 }.into()
220}
221
222pub(crate) fn get_crate_name() -> proc_macro2::TokenStream {
223 let found_crate = proc_macro_crate::crate_name("derse").unwrap_or_else(|err| {
224 eprintln!("Warning: {}\n => defaulting to `crate`", err,);
225 proc_macro_crate::FoundCrate::Itself
226 });
227
228 match found_crate {
229 proc_macro_crate::FoundCrate::Itself => quote! { crate },
230 proc_macro_crate::FoundCrate::Name(name) => {
231 let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
232 quote! { ::#ident }
233 }
234 }
235}