1use crate::{attr, bound, fallback};
2use proc_macro2::{Span, TokenStream};
3use quote::quote;
4use syn::{
5 parse_quote, Data, DataEnum, DataStruct, DeriveInput, Error, Fields, FieldsNamed, Result,
6};
7
8pub fn derive(input: &DeriveInput) -> TokenStream {
9 match try_expand(input) {
10 Ok(expanded) => expanded,
11 Err(error) => fallback::de(input, error),
15 }
16}
17
18fn try_expand(input: &DeriveInput) -> Result<TokenStream> {
19 match &input.data {
20 Data::Struct(DataStruct {
21 fields: Fields::Named(fields),
22 ..
23 }) => derive_struct(input, fields),
24 Data::Enum(enumeration) => derive_enum(input, enumeration),
25 Data::Struct(_) => Err(Error::new(
26 Span::call_site(),
27 "currently only structs with named fields are supported",
28 )),
29 Data::Union(_) => Err(Error::new(
30 Span::call_site(),
31 "currently only structs and enums are supported by this derive",
32 )),
33 }
34}
35
36pub fn derive_struct(input: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream> {
37 let ident = &input.ident;
38 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
39
40 let fieldname = fields.named.iter().map(|f| &f.ident).collect::<Vec<_>>();
41 let fieldty = fields.named.iter().map(|f| &f.ty);
42 let fieldstr = fields
43 .named
44 .iter()
45 .map(attr::name_of_field)
46 .collect::<Result<Vec<_>>>()?;
47
48 let wrapper_generics = bound::with_lifetime_bound(&input.generics, "'__a");
49 let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
50 let bound = parse_quote!(miniserde::Deserialize);
51 let bounded_where_clause = bound::where_clause_with_bound(&input.generics, bound);
52
53 Ok(quote! {
54 #[allow(deprecated, non_upper_case_globals)]
55 const _: () = {
56 #[repr(C)]
57 struct __Visitor #impl_generics #where_clause {
58 __out: miniserde::__private::Option<#ident #ty_generics>,
59 }
60
61 impl #impl_generics miniserde::Deserialize for #ident #ty_generics #bounded_where_clause {
62 fn begin(__out: &mut miniserde::__private::Option<Self>) -> &mut dyn miniserde::de::Visitor {
63 unsafe {
64 &mut *{
65 __out
66 as *mut miniserde::__private::Option<Self>
67 as *mut __Visitor #ty_generics
68 }
69 }
70 }
71 }
72
73 impl #impl_generics miniserde::de::Visitor for __Visitor #ty_generics #bounded_where_clause {
74 fn map(&mut self) -> miniserde::Result<miniserde::__private::Box<dyn miniserde::de::Map + '_>> {
75 Ok(miniserde::__private::Box::new(__State {
76 #(
77 #fieldname: miniserde::Deserialize::default(),
78 )*
79 __out: &mut self.__out,
80 }))
81 }
82 }
83
84 struct __State #wrapper_impl_generics #where_clause {
85 #(
86 #fieldname: miniserde::__private::Option<#fieldty>,
87 )*
88 __out: &'__a mut miniserde::__private::Option<#ident #ty_generics>,
89 }
90
91 impl #wrapper_impl_generics miniserde::de::Map for __State #wrapper_ty_generics #bounded_where_clause {
92 fn key(&mut self, __k: &miniserde::__private::str) -> miniserde::Result<&mut dyn miniserde::de::Visitor> {
93 match __k {
94 #(
95 #fieldstr => miniserde::__private::Ok(miniserde::Deserialize::begin(&mut self.#fieldname)),
96 )*
97 _ => miniserde::__private::Ok(<dyn miniserde::de::Visitor>::ignore()),
98 }
99 }
100
101 fn finish(&mut self) -> miniserde::Result<()> {
102 #(
103 let #fieldname = self.#fieldname.take().ok_or(miniserde::Error)?;
104 )*
105 *self.__out = miniserde::__private::Some(#ident {
106 #(
107 #fieldname,
108 )*
109 });
110 miniserde::__private::Ok(())
111 }
112 }
113 };
114 })
115}
116
117pub fn derive_enum(input: &DeriveInput, enumeration: &DataEnum) -> Result<TokenStream> {
118 if input.generics.lt_token.is_some() || input.generics.where_clause.is_some() {
119 return Err(Error::new(
120 Span::call_site(),
121 "Enums with generics are not supported",
122 ));
123 }
124
125 let ident = &input.ident;
126
127 let var_idents = enumeration
128 .variants
129 .iter()
130 .map(|variant| match variant.fields {
131 Fields::Unit => Ok(&variant.ident),
132 _ => Err(Error::new_spanned(
133 variant,
134 "Invalid variant: only simple enum variants without fields are supported",
135 )),
136 })
137 .collect::<Result<Vec<_>>>()?;
138 let names = enumeration
139 .variants
140 .iter()
141 .map(attr::name_of_variant)
142 .collect::<Result<Vec<_>>>()?;
143
144 Ok(quote! {
145 #[allow(deprecated, non_upper_case_globals)]
146 const _: () = {
147 #[repr(C)]
148 struct __Visitor {
149 __out: miniserde::__private::Option<#ident>,
150 }
151
152 impl miniserde::Deserialize for #ident {
153 fn begin(__out: &mut miniserde::__private::Option<Self>) -> &mut dyn miniserde::de::Visitor {
154 unsafe {
155 &mut *{
156 __out
157 as *mut miniserde::__private::Option<Self>
158 as *mut __Visitor
159 }
160 }
161 }
162 }
163
164 impl miniserde::de::Visitor for __Visitor {
165 fn string(&mut self, s: &miniserde::__private::str) -> miniserde::Result<()> {
166 let value = match s {
167 #( #names => #ident::#var_idents, )*
168 _ => return miniserde::__private::Err(miniserde::Error),
169 };
170 self.__out = miniserde::__private::Some(value);
171 miniserde::__private::Ok(())
172 }
173 }
174 };
175 })
176}