]>
Commit | Line | Data |
---|---|---|
8faf50e0 XL |
1 | use proc_macro2::{Literal, Span, TokenStream}; |
2 | use quote::ToTokens; | |
0531ce1d XL |
3 | use syn::punctuated::Punctuated; |
4 | use syn::spanned::Spanned; | |
83c7162d | 5 | use syn::{self, Ident, Index, Member}; |
3b2f2976 XL |
6 | |
7 | use bound; | |
f9f354fc | 8 | use dummy; |
ff7c6d11 | 9 | use fragment::{Expr, Fragment, Match, Stmts}; |
83c7162d | 10 | use internals::ast::{Container, Data, Field, Style, Variant}; |
5869c6ff | 11 | use internals::{attr, replace_receiver, ungroup, Ctxt, Derive}; |
8faf50e0 | 12 | use pretend; |
3b2f2976 XL |
13 | |
14 | use std::collections::BTreeSet; | |
fc512014 | 15 | use std::ptr; |
3b2f2976 | 16 | |
5869c6ff XL |
17 | pub fn expand_derive_deserialize( |
18 | input: &mut syn::DeriveInput, | |
19 | ) -> Result<TokenStream, Vec<syn::Error>> { | |
20 | replace_receiver(input); | |
21 | ||
8faf50e0 | 22 | let ctxt = Ctxt::new(); |
0731742a XL |
23 | let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) { |
24 | Some(cont) => cont, | |
25 | None => return Err(ctxt.check().unwrap_err()), | |
26 | }; | |
8faf50e0 | 27 | precondition(&ctxt, &cont); |
f9f354fc | 28 | ctxt.check()?; |
3b2f2976 XL |
29 | |
30 | let ident = &cont.ident; | |
31 | let params = Parameters::new(&cont); | |
32 | let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); | |
3b2f2976 | 33 | let body = Stmts(deserialize_body(&cont, ¶ms)); |
ea8adc8c | 34 | let delife = params.borrowed.de_lifetime(); |
f9f354fc | 35 | let serde = cont.attrs.serde_path(); |
3b2f2976 XL |
36 | |
37 | let impl_block = if let Some(remote) = cont.attrs.remote() { | |
38 | let vis = &input.vis; | |
c295e0f8 | 39 | let used = pretend::pretend_used(&cont, params.is_packed); |
3b2f2976 XL |
40 | quote! { |
41 | impl #de_impl_generics #ident #ty_generics #where_clause { | |
5869c6ff | 42 | #vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error> |
8faf50e0 | 43 | where |
f9f354fc | 44 | __D: #serde::Deserializer<#delife>, |
3b2f2976 | 45 | { |
8faf50e0 | 46 | #used |
3b2f2976 XL |
47 | #body |
48 | } | |
49 | } | |
50 | } | |
51 | } else { | |
ff7c6d11 XL |
52 | let fn_deserialize_in_place = deserialize_in_place_body(&cont, ¶ms); |
53 | ||
3b2f2976 XL |
54 | quote! { |
55 | #[automatically_derived] | |
f9f354fc | 56 | impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause { |
5869c6ff | 57 | fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<Self, __D::Error> |
8faf50e0 | 58 | where |
f9f354fc | 59 | __D: #serde::Deserializer<#delife>, |
3b2f2976 XL |
60 | { |
61 | #body | |
62 | } | |
ff7c6d11 XL |
63 | |
64 | #fn_deserialize_in_place | |
3b2f2976 XL |
65 | } |
66 | } | |
67 | }; | |
68 | ||
f9f354fc XL |
69 | Ok(dummy::wrap_in_const( |
70 | cont.attrs.custom_serde_path(), | |
71 | "DESERIALIZE", | |
72 | ident, | |
73 | impl_block, | |
74 | )) | |
3b2f2976 XL |
75 | } |
76 | ||
8faf50e0 XL |
77 | fn precondition(cx: &Ctxt, cont: &Container) { |
78 | precondition_sized(cx, cont); | |
79 | precondition_no_de_lifetime(cx, cont); | |
80 | } | |
81 | ||
82 | fn precondition_sized(cx: &Ctxt, cont: &Container) { | |
f9f354fc | 83 | if let Data::Struct(_, fields) = &cont.data { |
8faf50e0 | 84 | if let Some(last) = fields.last() { |
f035d41b | 85 | if let syn::Type::Slice(_) = ungroup(last.ty) { |
f9f354fc XL |
86 | cx.error_spanned_by( |
87 | cont.original, | |
88 | "cannot deserialize a dynamically sized struct", | |
89 | ); | |
8faf50e0 XL |
90 | } |
91 | } | |
92 | } | |
93 | } | |
94 | ||
95 | fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) { | |
96 | if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) { | |
97 | for param in cont.generics.lifetimes() { | |
98 | if param.lifetime.to_string() == "'de" { | |
0731742a XL |
99 | cx.error_spanned_by( |
100 | ¶m.lifetime, | |
101 | "cannot deserialize when there is a lifetime parameter called 'de", | |
102 | ); | |
8faf50e0 XL |
103 | return; |
104 | } | |
105 | } | |
106 | } | |
107 | } | |
108 | ||
3b2f2976 XL |
109 | struct Parameters { |
110 | /// Name of the type the `derive` is on. | |
111 | local: syn::Ident, | |
112 | ||
113 | /// Path to the type the impl is for. Either a single `Ident` for local | |
114 | /// types or `some::remote::Ident` for remote types. Does not include | |
115 | /// generic parameters. | |
116 | this: syn::Path, | |
117 | ||
118 | /// Generics including any explicit and inferred bounds for the impl. | |
119 | generics: syn::Generics, | |
120 | ||
121 | /// Lifetimes borrowed from the deserializer. These will become bounds on | |
122 | /// the `'de` lifetime of the deserializer. | |
ea8adc8c | 123 | borrowed: BorrowedLifetimes, |
3b2f2976 XL |
124 | |
125 | /// At least one field has a serde(getter) attribute, implying that the | |
126 | /// remote type has a private field. | |
127 | has_getter: bool, | |
c295e0f8 XL |
128 | |
129 | /// Type has a repr(packed) attribute. | |
130 | is_packed: bool, | |
3b2f2976 XL |
131 | } |
132 | ||
133 | impl Parameters { | |
134 | fn new(cont: &Container) -> Self { | |
8faf50e0 | 135 | let local = cont.ident.clone(); |
3b2f2976 XL |
136 | let this = match cont.attrs.remote() { |
137 | Some(remote) => remote.clone(), | |
8faf50e0 | 138 | None => cont.ident.clone().into(), |
3b2f2976 | 139 | }; |
3b2f2976 | 140 | let borrowed = borrowed_lifetimes(cont); |
ea8adc8c | 141 | let generics = build_generics(cont, &borrowed); |
0531ce1d | 142 | let has_getter = cont.data.has_getter(); |
c295e0f8 | 143 | let is_packed = cont.attrs.is_packed(); |
3b2f2976 XL |
144 | |
145 | Parameters { | |
f035d41b XL |
146 | local, |
147 | this, | |
148 | generics, | |
149 | borrowed, | |
150 | has_getter, | |
c295e0f8 | 151 | is_packed, |
3b2f2976 XL |
152 | } |
153 | } | |
154 | ||
155 | /// Type name to use in error messages and `&'static str` arguments to | |
156 | /// various Deserializer methods. | |
8faf50e0 | 157 | fn type_name(&self) -> String { |
f9f354fc | 158 | self.this.segments.last().unwrap().ident.to_string() |
3b2f2976 | 159 | } |
3b2f2976 XL |
160 | } |
161 | ||
162 | // All the generics in the input, plus a bound `T: Deserialize` for each generic | |
163 | // field type that will be deserialized by us, plus a bound `T: Default` for | |
164 | // each generic field type that will be set to a default value. | |
ea8adc8c | 165 | fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics { |
3b2f2976 XL |
166 | let generics = bound::without_defaults(cont.generics); |
167 | ||
168 | let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound); | |
169 | ||
8faf50e0 XL |
170 | let generics = |
171 | bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::de_bound); | |
172 | ||
3b2f2976 XL |
173 | match cont.attrs.de_bound() { |
174 | Some(predicates) => bound::with_where_predicates(&generics, predicates), | |
175 | None => { | |
176 | let generics = match *cont.attrs.default() { | |
5869c6ff XL |
177 | attr::Default::Default => bound::with_self_bound( |
178 | cont, | |
179 | &generics, | |
180 | &parse_quote!(_serde::__private::Default), | |
181 | ), | |
ff7c6d11 | 182 | attr::Default::None | attr::Default::Path(_) => generics, |
3b2f2976 XL |
183 | }; |
184 | ||
ea8adc8c | 185 | let delife = borrowed.de_lifetime(); |
3b2f2976 XL |
186 | let generics = bound::with_bound( |
187 | cont, | |
188 | &generics, | |
189 | needs_deserialize_bound, | |
0531ce1d | 190 | &parse_quote!(_serde::Deserialize<#delife>), |
3b2f2976 XL |
191 | ); |
192 | ||
193 | bound::with_bound( | |
194 | cont, | |
195 | &generics, | |
196 | requires_default, | |
5869c6ff | 197 | &parse_quote!(_serde::__private::Default), |
3b2f2976 XL |
198 | ) |
199 | } | |
200 | } | |
201 | } | |
202 | ||
8faf50e0 XL |
203 | // Fields with a `skip_deserializing` or `deserialize_with` attribute, or which |
204 | // belong to a variant with a `skip_deserializing` or `deserialize_with` | |
205 | // attribute, are not deserialized by us so we do not generate a bound. Fields | |
206 | // with a `bound` attribute specify their own bound so we do not generate one. | |
207 | // All other fields may need a `T: Deserialize` bound where T is the type of the | |
208 | // field. | |
ea8adc8c | 209 | fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { |
b7449926 XL |
210 | !field.skip_deserializing() |
211 | && field.deserialize_with().is_none() | |
212 | && field.de_bound().is_none() | |
8faf50e0 XL |
213 | && variant.map_or(true, |variant| { |
214 | !variant.skip_deserializing() | |
215 | && variant.deserialize_with().is_none() | |
216 | && variant.de_bound().is_none() | |
217 | }) | |
3b2f2976 XL |
218 | } |
219 | ||
220 | // Fields with a `default` attribute (not `default=...`), and fields with a | |
221 | // `skip_deserializing` attribute that do not also have `default=...`. | |
ea8adc8c | 222 | fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool { |
0531ce1d XL |
223 | if let attr::Default::Default = *field.default() { |
224 | true | |
225 | } else { | |
226 | false | |
227 | } | |
ea8adc8c XL |
228 | } |
229 | ||
230 | enum BorrowedLifetimes { | |
231 | Borrowed(BTreeSet<syn::Lifetime>), | |
232 | Static, | |
233 | } | |
234 | ||
235 | impl BorrowedLifetimes { | |
236 | fn de_lifetime(&self) -> syn::Lifetime { | |
237 | match *self { | |
83c7162d XL |
238 | BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de", Span::call_site()), |
239 | BorrowedLifetimes::Static => syn::Lifetime::new("'static", Span::call_site()), | |
ea8adc8c XL |
240 | } |
241 | } | |
242 | ||
243 | fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> { | |
f9f354fc XL |
244 | match self { |
245 | BorrowedLifetimes::Borrowed(bounds) => Some(syn::LifetimeDef { | |
ff7c6d11 | 246 | attrs: Vec::new(), |
83c7162d | 247 | lifetime: syn::Lifetime::new("'de", Span::call_site()), |
0531ce1d | 248 | colon_token: None, |
ff7c6d11 XL |
249 | bounds: bounds.iter().cloned().collect(), |
250 | }), | |
ea8adc8c XL |
251 | BorrowedLifetimes::Static => None, |
252 | } | |
253 | } | |
3b2f2976 XL |
254 | } |
255 | ||
256 | // The union of lifetimes borrowed by each field of the container. | |
257 | // | |
258 | // These turn into bounds on the `'de` lifetime of the Deserialize impl. If | |
259 | // lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is: | |
260 | // | |
261 | // impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c> | |
ea8adc8c XL |
262 | // |
263 | // If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant | |
264 | // and we use plain `'static` instead of `'de`. | |
265 | fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes { | |
3b2f2976 | 266 | let mut lifetimes = BTreeSet::new(); |
0531ce1d | 267 | for field in cont.data.all_fields() { |
abe05a73 XL |
268 | if !field.attrs.skip_deserializing() { |
269 | lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned()); | |
270 | } | |
3b2f2976 | 271 | } |
0531ce1d | 272 | if lifetimes.iter().any(|b| b.to_string() == "'static") { |
ea8adc8c XL |
273 | BorrowedLifetimes::Static |
274 | } else { | |
275 | BorrowedLifetimes::Borrowed(lifetimes) | |
276 | } | |
3b2f2976 XL |
277 | } |
278 | ||
279 | fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { | |
8faf50e0 XL |
280 | if cont.attrs.transparent() { |
281 | deserialize_transparent(cont, params) | |
282 | } else if let Some(type_from) = cont.attrs.type_from() { | |
0531ce1d | 283 | deserialize_from(type_from) |
f9f354fc XL |
284 | } else if let Some(type_try_from) = cont.attrs.type_try_from() { |
285 | deserialize_try_from(type_try_from) | |
3b2f2976 | 286 | } else if let attr::Identifier::No = cont.attrs.identifier() { |
f9f354fc XL |
287 | match &cont.data { |
288 | Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs), | |
289 | Data::Struct(Style::Struct, fields) => { | |
0531ce1d | 290 | deserialize_struct(None, params, fields, &cont.attrs, None, &Untagged::No) |
3b2f2976 | 291 | } |
f9f354fc | 292 | Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { |
3b2f2976 XL |
293 | deserialize_tuple(None, params, fields, &cont.attrs, None) |
294 | } | |
0531ce1d | 295 | Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs), |
3b2f2976 XL |
296 | } |
297 | } else { | |
f9f354fc XL |
298 | match &cont.data { |
299 | Data::Enum(variants) => deserialize_custom_identifier(params, variants, &cont.attrs), | |
0531ce1d | 300 | Data::Struct(_, _) => unreachable!("checked in serde_derive_internals"), |
3b2f2976 XL |
301 | } |
302 | } | |
303 | } | |
304 | ||
ff7c6d11 XL |
305 | #[cfg(feature = "deserialize_in_place")] |
306 | fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> { | |
307 | // Only remote derives have getters, and we do not generate | |
308 | // deserialize_in_place for remote derives. | |
309 | assert!(!params.has_getter); | |
310 | ||
8faf50e0 XL |
311 | if cont.attrs.transparent() |
312 | || cont.attrs.type_from().is_some() | |
f9f354fc | 313 | || cont.attrs.type_try_from().is_some() |
8faf50e0 XL |
314 | || cont.attrs.identifier().is_some() |
315 | || cont | |
316 | .data | |
ff7c6d11 XL |
317 | .all_fields() |
318 | .all(|f| f.attrs.deserialize_with().is_some()) | |
319 | { | |
320 | return None; | |
321 | } | |
322 | ||
f9f354fc XL |
323 | let code = match &cont.data { |
324 | Data::Struct(Style::Struct, fields) => { | |
325 | deserialize_struct_in_place(None, params, fields, &cont.attrs, None)? | |
ff7c6d11 | 326 | } |
f9f354fc | 327 | Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { |
ff7c6d11 XL |
328 | deserialize_tuple_in_place(None, params, fields, &cont.attrs, None) |
329 | } | |
0531ce1d | 330 | Data::Enum(_) | Data::Struct(Style::Unit, _) => { |
ff7c6d11 XL |
331 | return None; |
332 | } | |
333 | }; | |
334 | ||
335 | let delife = params.borrowed.de_lifetime(); | |
336 | let stmts = Stmts(code); | |
337 | ||
338 | let fn_deserialize_in_place = quote_block! { | |
5869c6ff | 339 | fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::__private::Result<(), __D::Error> |
8faf50e0 XL |
340 | where |
341 | __D: _serde::Deserializer<#delife>, | |
ff7c6d11 XL |
342 | { |
343 | #stmts | |
344 | } | |
345 | }; | |
346 | ||
347 | Some(Stmts(fn_deserialize_in_place)) | |
348 | } | |
349 | ||
350 | #[cfg(not(feature = "deserialize_in_place"))] | |
351 | fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> { | |
352 | None | |
353 | } | |
354 | ||
8faf50e0 | 355 | fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment { |
f9f354fc XL |
356 | let fields = match &cont.data { |
357 | Data::Struct(_, fields) => fields, | |
8faf50e0 XL |
358 | Data::Enum(_) => unreachable!(), |
359 | }; | |
360 | ||
361 | let this = ¶ms.this; | |
362 | let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap(); | |
363 | ||
364 | let path = match transparent_field.attrs.deserialize_with() { | |
365 | Some(path) => quote!(#path), | |
0731742a XL |
366 | None => { |
367 | let span = transparent_field.original.span(); | |
368 | quote_spanned!(span=> _serde::Deserialize::deserialize) | |
f9f354fc | 369 | } |
8faf50e0 XL |
370 | }; |
371 | ||
372 | let assign = fields.iter().map(|field| { | |
373 | let member = &field.member; | |
fc512014 | 374 | if ptr::eq(field, transparent_field) { |
8faf50e0 XL |
375 | quote!(#member: __transparent) |
376 | } else { | |
f9f354fc | 377 | let value = match field.attrs.default() { |
5869c6ff | 378 | attr::Default::Default => quote!(_serde::__private::Default::default()), |
f9f354fc | 379 | attr::Default::Path(path) => quote!(#path()), |
5869c6ff | 380 | attr::Default::None => quote!(_serde::__private::PhantomData), |
8faf50e0 XL |
381 | }; |
382 | quote!(#member: #value) | |
383 | } | |
384 | }); | |
385 | ||
386 | quote_block! { | |
5869c6ff | 387 | _serde::__private::Result::map( |
8faf50e0 XL |
388 | #path(__deserializer), |
389 | |__transparent| #this { #(#assign),* }) | |
390 | } | |
391 | } | |
392 | ||
0531ce1d | 393 | fn deserialize_from(type_from: &syn::Type) -> Fragment { |
3b2f2976 | 394 | quote_block! { |
5869c6ff | 395 | _serde::__private::Result::map( |
0531ce1d | 396 | <#type_from as _serde::Deserialize>::deserialize(__deserializer), |
5869c6ff | 397 | _serde::__private::From::from) |
3b2f2976 XL |
398 | } |
399 | } | |
400 | ||
f9f354fc XL |
401 | fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment { |
402 | quote_block! { | |
5869c6ff | 403 | _serde::__private::Result::and_then( |
f9f354fc | 404 | <#type_try_from as _serde::Deserialize>::deserialize(__deserializer), |
5869c6ff | 405 | |v| _serde::__private::TryFrom::try_from(v).map_err(_serde::de::Error::custom)) |
f9f354fc XL |
406 | } |
407 | } | |
408 | ||
3b2f2976 XL |
409 | fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment { |
410 | let this = ¶ms.this; | |
411 | let type_name = cattrs.name().deserialize_name(); | |
412 | ||
413 | let expecting = format!("unit struct {}", params.type_name()); | |
5869c6ff | 414 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
3b2f2976 XL |
415 | |
416 | quote_block! { | |
417 | struct __Visitor; | |
418 | ||
419 | impl<'de> _serde::de::Visitor<'de> for __Visitor { | |
420 | type Value = #this; | |
421 | ||
5869c6ff XL |
422 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
423 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
424 | } |
425 | ||
426 | #[inline] | |
5869c6ff | 427 | fn visit_unit<__E>(self) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
428 | where |
429 | __E: _serde::de::Error, | |
3b2f2976 | 430 | { |
5869c6ff | 431 | _serde::__private::Ok(#this) |
3b2f2976 XL |
432 | } |
433 | } | |
434 | ||
435 | _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor) | |
436 | } | |
437 | } | |
438 | ||
439 | fn deserialize_tuple( | |
440 | variant_ident: Option<&syn::Ident>, | |
441 | params: &Parameters, | |
442 | fields: &[Field], | |
443 | cattrs: &attr::Container, | |
8faf50e0 | 444 | deserializer: Option<TokenStream>, |
3b2f2976 XL |
445 | ) -> Fragment { |
446 | let this = ¶ms.this; | |
ff7c6d11 XL |
447 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = |
448 | split_with_de_lifetime(params); | |
ea8adc8c | 449 | let delife = params.borrowed.de_lifetime(); |
3b2f2976 | 450 | |
0531ce1d XL |
451 | assert!(!cattrs.has_flatten()); |
452 | ||
3b2f2976 XL |
453 | // If there are getters (implying private fields), construct the local type |
454 | // and use an `Into` conversion to get the remote type. If there are no | |
455 | // getters then construct the target type directly. | |
456 | let construct = if params.has_getter { | |
457 | let local = ¶ms.local; | |
458 | quote!(#local) | |
459 | } else { | |
460 | quote!(#this) | |
461 | }; | |
462 | ||
463 | let is_enum = variant_ident.is_some(); | |
464 | let type_path = match variant_ident { | |
f9f354fc | 465 | Some(variant_ident) => quote!(#construct::#variant_ident), |
3b2f2976 XL |
466 | None => construct, |
467 | }; | |
468 | let expecting = match variant_ident { | |
469 | Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident), | |
470 | None => format!("tuple struct {}", params.type_name()), | |
471 | }; | |
5869c6ff | 472 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
3b2f2976 XL |
473 | |
474 | let nfields = fields.len(); | |
475 | ||
476 | let visit_newtype_struct = if !is_enum && nfields == 1 { | |
477 | Some(deserialize_newtype_struct(&type_path, params, &fields[0])) | |
478 | } else { | |
479 | None | |
480 | }; | |
481 | ||
8faf50e0 | 482 | let visit_seq = Stmts(deserialize_seq( |
94222f64 | 483 | &type_path, params, fields, false, cattrs, expecting, |
8faf50e0 | 484 | )); |
3b2f2976 XL |
485 | |
486 | let visitor_expr = quote! { | |
487 | __Visitor { | |
5869c6ff XL |
488 | marker: _serde::__private::PhantomData::<#this #ty_generics>, |
489 | lifetime: _serde::__private::PhantomData, | |
3b2f2976 XL |
490 | } |
491 | }; | |
492 | let dispatch = if let Some(deserializer) = deserializer { | |
493 | quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) | |
494 | } else if is_enum { | |
495 | quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) | |
496 | } else if nfields == 1 { | |
497 | let type_name = cattrs.name().deserialize_name(); | |
498 | quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) | |
499 | } else { | |
500 | let type_name = cattrs.name().deserialize_name(); | |
501 | quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) | |
502 | }; | |
503 | ||
ff7c6d11 | 504 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); |
3b2f2976 XL |
505 | let visitor_var = if all_skipped { |
506 | quote!(_) | |
507 | } else { | |
508 | quote!(mut __seq) | |
509 | }; | |
510 | ||
511 | quote_block! { | |
512 | struct __Visitor #de_impl_generics #where_clause { | |
5869c6ff XL |
513 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
514 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
515 | } |
516 | ||
ea8adc8c | 517 | impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { |
3b2f2976 XL |
518 | type Value = #this #ty_generics; |
519 | ||
5869c6ff XL |
520 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
521 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
522 | } |
523 | ||
524 | #visit_newtype_struct | |
525 | ||
526 | #[inline] | |
5869c6ff | 527 | fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
528 | where |
529 | __A: _serde::de::SeqAccess<#delife>, | |
3b2f2976 XL |
530 | { |
531 | #visit_seq | |
532 | } | |
533 | } | |
534 | ||
535 | #dispatch | |
536 | } | |
537 | } | |
538 | ||
ff7c6d11 XL |
539 | #[cfg(feature = "deserialize_in_place")] |
540 | fn deserialize_tuple_in_place( | |
8faf50e0 | 541 | variant_ident: Option<syn::Ident>, |
ff7c6d11 XL |
542 | params: &Parameters, |
543 | fields: &[Field], | |
544 | cattrs: &attr::Container, | |
8faf50e0 | 545 | deserializer: Option<TokenStream>, |
ff7c6d11 XL |
546 | ) -> Fragment { |
547 | let this = ¶ms.this; | |
548 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = | |
549 | split_with_de_lifetime(params); | |
550 | let delife = params.borrowed.de_lifetime(); | |
551 | ||
0531ce1d XL |
552 | assert!(!cattrs.has_flatten()); |
553 | ||
ff7c6d11 XL |
554 | let is_enum = variant_ident.is_some(); |
555 | let expecting = match variant_ident { | |
556 | Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident), | |
557 | None => format!("tuple struct {}", params.type_name()), | |
558 | }; | |
5869c6ff | 559 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
ff7c6d11 XL |
560 | |
561 | let nfields = fields.len(); | |
562 | ||
563 | let visit_newtype_struct = if !is_enum && nfields == 1 { | |
564 | Some(deserialize_newtype_struct_in_place(params, &fields[0])) | |
565 | } else { | |
566 | None | |
567 | }; | |
568 | ||
94222f64 | 569 | let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting)); |
ff7c6d11 XL |
570 | |
571 | let visitor_expr = quote! { | |
572 | __Visitor { | |
573 | place: __place, | |
5869c6ff | 574 | lifetime: _serde::__private::PhantomData, |
ff7c6d11 XL |
575 | } |
576 | }; | |
577 | ||
578 | let dispatch = if let Some(deserializer) = deserializer { | |
579 | quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) | |
580 | } else if is_enum { | |
581 | quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) | |
582 | } else if nfields == 1 { | |
583 | let type_name = cattrs.name().deserialize_name(); | |
584 | quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) | |
585 | } else { | |
586 | let type_name = cattrs.name().deserialize_name(); | |
587 | quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) | |
588 | }; | |
589 | ||
590 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); | |
591 | let visitor_var = if all_skipped { | |
592 | quote!(_) | |
593 | } else { | |
594 | quote!(mut __seq) | |
595 | }; | |
596 | ||
597 | let in_place_impl_generics = de_impl_generics.in_place(); | |
598 | let in_place_ty_generics = de_ty_generics.in_place(); | |
599 | let place_life = place_lifetime(); | |
600 | ||
601 | quote_block! { | |
602 | struct __Visitor #in_place_impl_generics #where_clause { | |
603 | place: &#place_life mut #this #ty_generics, | |
5869c6ff | 604 | lifetime: _serde::__private::PhantomData<&#delife ()>, |
ff7c6d11 XL |
605 | } |
606 | ||
607 | impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { | |
608 | type Value = (); | |
609 | ||
5869c6ff XL |
610 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
611 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
ff7c6d11 XL |
612 | } |
613 | ||
614 | #visit_newtype_struct | |
615 | ||
616 | #[inline] | |
5869c6ff | 617 | fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
618 | where |
619 | __A: _serde::de::SeqAccess<#delife>, | |
ff7c6d11 XL |
620 | { |
621 | #visit_seq | |
622 | } | |
623 | } | |
624 | ||
625 | #dispatch | |
626 | } | |
627 | } | |
628 | ||
3b2f2976 | 629 | fn deserialize_seq( |
8faf50e0 | 630 | type_path: &TokenStream, |
3b2f2976 XL |
631 | params: &Parameters, |
632 | fields: &[Field], | |
633 | is_struct: bool, | |
634 | cattrs: &attr::Container, | |
8faf50e0 | 635 | expecting: &str, |
3b2f2976 XL |
636 | ) -> Fragment { |
637 | let vars = (0..fields.len()).map(field_i as fn(_) -> _); | |
638 | ||
639 | let deserialized_count = fields | |
640 | .iter() | |
641 | .filter(|field| !field.attrs.skip_deserializing()) | |
642 | .count(); | |
8faf50e0 XL |
643 | let expecting = if deserialized_count == 1 { |
644 | format!("{} with 1 element", expecting) | |
645 | } else { | |
646 | format!("{} with {} elements", expecting, deserialized_count) | |
647 | }; | |
5869c6ff | 648 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
3b2f2976 | 649 | |
8faf50e0 | 650 | let mut index_in_seq = 0_usize; |
ff7c6d11 XL |
651 | let let_values = vars.clone().zip(fields).map(|(var, field)| { |
652 | if field.attrs.skip_deserializing() { | |
0531ce1d | 653 | let default = Expr(expr_is_missing(field, cattrs)); |
ff7c6d11 XL |
654 | quote! { |
655 | let #var = #default; | |
656 | } | |
657 | } else { | |
658 | let visit = match field.attrs.deserialize_with() { | |
659 | None => { | |
8faf50e0 | 660 | let field_ty = field.ty; |
83c7162d XL |
661 | let span = field.original.span(); |
662 | let func = | |
663 | quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>); | |
0531ce1d | 664 | quote!(try!(#func(&mut __seq))) |
3b2f2976 | 665 | } |
ff7c6d11 XL |
666 | Some(path) => { |
667 | let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); | |
668 | quote!({ | |
669 | #wrapper | |
5869c6ff | 670 | _serde::__private::Option::map( |
ff7c6d11 XL |
671 | try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)), |
672 | |__wrap| __wrap.value) | |
673 | }) | |
674 | } | |
675 | }; | |
f9f354fc | 676 | let value_if_none = match field.attrs.default() { |
5869c6ff | 677 | attr::Default::Default => quote!(_serde::__private::Default::default()), |
f9f354fc XL |
678 | attr::Default::Path(path) => quote!(#path()), |
679 | attr::Default::None => quote!( | |
5869c6ff | 680 | return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); |
f9f354fc XL |
681 | ), |
682 | }; | |
ff7c6d11 XL |
683 | let assign = quote! { |
684 | let #var = match #visit { | |
5869c6ff XL |
685 | _serde::__private::Some(__value) => __value, |
686 | _serde::__private::None => { | |
f9f354fc | 687 | #value_if_none |
3b2f2976 XL |
688 | } |
689 | }; | |
ff7c6d11 XL |
690 | }; |
691 | index_in_seq += 1; | |
692 | assign | |
693 | } | |
694 | }); | |
3b2f2976 XL |
695 | |
696 | let mut result = if is_struct { | |
8faf50e0 XL |
697 | let names = fields.iter().map(|f| &f.member); |
698 | quote! { | |
3b2f2976 XL |
699 | #type_path { #( #names: #vars ),* } |
700 | } | |
701 | } else { | |
8faf50e0 | 702 | quote! { |
3b2f2976 XL |
703 | #type_path ( #(#vars),* ) |
704 | } | |
705 | }; | |
706 | ||
707 | if params.has_getter { | |
708 | let this = ¶ms.this; | |
709 | result = quote! { | |
5869c6ff | 710 | _serde::__private::Into::<#this>::into(#result) |
3b2f2976 XL |
711 | }; |
712 | } | |
713 | ||
f9f354fc | 714 | let let_default = match cattrs.default() { |
ff7c6d11 | 715 | attr::Default::Default => Some(quote!( |
5869c6ff | 716 | let __default: Self::Value = _serde::__private::Default::default(); |
ff7c6d11 | 717 | )), |
f9f354fc | 718 | attr::Default::Path(path) => Some(quote!( |
ff7c6d11 XL |
719 | let __default: Self::Value = #path(); |
720 | )), | |
721 | attr::Default::None => { | |
722 | // We don't need the default value, to prevent an unused variable warning | |
723 | // we'll leave the line empty. | |
724 | None | |
725 | } | |
726 | }; | |
727 | ||
3b2f2976 | 728 | quote_block! { |
ff7c6d11 | 729 | #let_default |
3b2f2976 | 730 | #(#let_values)* |
5869c6ff | 731 | _serde::__private::Ok(#result) |
3b2f2976 XL |
732 | } |
733 | } | |
734 | ||
ff7c6d11 XL |
735 | #[cfg(feature = "deserialize_in_place")] |
736 | fn deserialize_seq_in_place( | |
737 | params: &Parameters, | |
738 | fields: &[Field], | |
739 | cattrs: &attr::Container, | |
8faf50e0 | 740 | expecting: &str, |
ff7c6d11 | 741 | ) -> Fragment { |
ff7c6d11 XL |
742 | let deserialized_count = fields |
743 | .iter() | |
744 | .filter(|field| !field.attrs.skip_deserializing()) | |
745 | .count(); | |
8faf50e0 XL |
746 | let expecting = if deserialized_count == 1 { |
747 | format!("{} with 1 element", expecting) | |
748 | } else { | |
749 | format!("{} with {} elements", expecting, deserialized_count) | |
750 | }; | |
5869c6ff | 751 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
ff7c6d11 XL |
752 | |
753 | let mut index_in_seq = 0usize; | |
8faf50e0 XL |
754 | let write_values = fields.iter().map(|field| { |
755 | let member = &field.member; | |
ff7c6d11 | 756 | |
8faf50e0 XL |
757 | if field.attrs.skip_deserializing() { |
758 | let default = Expr(expr_is_missing(field, cattrs)); | |
759 | quote! { | |
760 | self.place.#member = #default; | |
761 | } | |
762 | } else { | |
f9f354fc XL |
763 | let value_if_none = match field.attrs.default() { |
764 | attr::Default::Default => quote!( | |
5869c6ff | 765 | self.place.#member = _serde::__private::Default::default(); |
f9f354fc XL |
766 | ), |
767 | attr::Default::Path(path) => quote!( | |
768 | self.place.#member = #path(); | |
769 | ), | |
770 | attr::Default::None => quote!( | |
5869c6ff | 771 | return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); |
f9f354fc | 772 | ), |
8faf50e0 XL |
773 | }; |
774 | let write = match field.attrs.deserialize_with() { | |
775 | None => { | |
776 | quote! { | |
5869c6ff XL |
777 | if let _serde::__private::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, |
778 | _serde::__private::de::InPlaceSeed(&mut self.place.#member))) | |
8faf50e0 | 779 | { |
f9f354fc | 780 | #value_if_none |
ff7c6d11 XL |
781 | } |
782 | } | |
8faf50e0 XL |
783 | } |
784 | Some(path) => { | |
785 | let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); | |
786 | quote!({ | |
f9f354fc XL |
787 | #wrapper |
788 | match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) { | |
5869c6ff | 789 | _serde::__private::Some(__wrap) => { |
f9f354fc | 790 | self.place.#member = __wrap.value; |
ff7c6d11 | 791 | } |
5869c6ff | 792 | _serde::__private::None => { |
f9f354fc XL |
793 | #value_if_none |
794 | } | |
795 | } | |
796 | }) | |
8faf50e0 XL |
797 | } |
798 | }; | |
799 | index_in_seq += 1; | |
800 | write | |
801 | } | |
802 | }); | |
ff7c6d11 XL |
803 | |
804 | let this = ¶ms.this; | |
805 | let (_, ty_generics, _) = params.generics.split_for_impl(); | |
f9f354fc | 806 | let let_default = match cattrs.default() { |
ff7c6d11 | 807 | attr::Default::Default => Some(quote!( |
5869c6ff | 808 | let __default: #this #ty_generics = _serde::__private::Default::default(); |
ff7c6d11 | 809 | )), |
f9f354fc | 810 | attr::Default::Path(path) => Some(quote!( |
ff7c6d11 XL |
811 | let __default: #this #ty_generics = #path(); |
812 | )), | |
813 | attr::Default::None => { | |
814 | // We don't need the default value, to prevent an unused variable warning | |
815 | // we'll leave the line empty. | |
816 | None | |
817 | } | |
818 | }; | |
819 | ||
820 | quote_block! { | |
821 | #let_default | |
822 | #(#write_values)* | |
5869c6ff | 823 | _serde::__private::Ok(()) |
ff7c6d11 XL |
824 | } |
825 | } | |
826 | ||
8faf50e0 XL |
827 | fn deserialize_newtype_struct( |
828 | type_path: &TokenStream, | |
829 | params: &Parameters, | |
830 | field: &Field, | |
831 | ) -> TokenStream { | |
ea8adc8c | 832 | let delife = params.borrowed.de_lifetime(); |
8faf50e0 | 833 | let field_ty = field.ty; |
ea8adc8c | 834 | |
3b2f2976 XL |
835 | let value = match field.attrs.deserialize_with() { |
836 | None => { | |
0731742a XL |
837 | let span = field.original.span(); |
838 | let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); | |
3b2f2976 | 839 | quote! { |
0731742a | 840 | try!(#func(__e)) |
3b2f2976 XL |
841 | } |
842 | } | |
843 | Some(path) => { | |
8faf50e0 XL |
844 | quote! { |
845 | try!(#path(__e)) | |
846 | } | |
3b2f2976 XL |
847 | } |
848 | }; | |
849 | ||
8faf50e0 | 850 | let mut result = quote!(#type_path(__field0)); |
3b2f2976 XL |
851 | if params.has_getter { |
852 | let this = ¶ms.this; | |
853 | result = quote! { | |
5869c6ff | 854 | _serde::__private::Into::<#this>::into(#result) |
3b2f2976 XL |
855 | }; |
856 | } | |
857 | ||
858 | quote! { | |
859 | #[inline] | |
5869c6ff | 860 | fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error> |
8faf50e0 XL |
861 | where |
862 | __E: _serde::Deserializer<#delife>, | |
3b2f2976 | 863 | { |
8faf50e0 | 864 | let __field0: #field_ty = #value; |
5869c6ff | 865 | _serde::__private::Ok(#result) |
3b2f2976 XL |
866 | } |
867 | } | |
868 | } | |
869 | ||
ff7c6d11 | 870 | #[cfg(feature = "deserialize_in_place")] |
8faf50e0 | 871 | fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream { |
b7449926 XL |
872 | // We do not generate deserialize_in_place if every field has a |
873 | // deserialize_with. | |
ff7c6d11 XL |
874 | assert!(field.attrs.deserialize_with().is_none()); |
875 | ||
876 | let delife = params.borrowed.de_lifetime(); | |
877 | ||
878 | quote! { | |
879 | #[inline] | |
5869c6ff | 880 | fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error> |
8faf50e0 XL |
881 | where |
882 | __E: _serde::Deserializer<#delife>, | |
ff7c6d11 | 883 | { |
8faf50e0 | 884 | _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0) |
ff7c6d11 XL |
885 | } |
886 | } | |
887 | } | |
888 | ||
ea8adc8c XL |
889 | enum Untagged { |
890 | Yes, | |
891 | No, | |
892 | } | |
893 | ||
3b2f2976 XL |
894 | fn deserialize_struct( |
895 | variant_ident: Option<&syn::Ident>, | |
896 | params: &Parameters, | |
897 | fields: &[Field], | |
898 | cattrs: &attr::Container, | |
8faf50e0 | 899 | deserializer: Option<TokenStream>, |
0531ce1d | 900 | untagged: &Untagged, |
3b2f2976 XL |
901 | ) -> Fragment { |
902 | let is_enum = variant_ident.is_some(); | |
3b2f2976 XL |
903 | |
904 | let this = ¶ms.this; | |
ff7c6d11 XL |
905 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = |
906 | split_with_de_lifetime(params); | |
ea8adc8c | 907 | let delife = params.borrowed.de_lifetime(); |
3b2f2976 XL |
908 | |
909 | // If there are getters (implying private fields), construct the local type | |
910 | // and use an `Into` conversion to get the remote type. If there are no | |
911 | // getters then construct the target type directly. | |
912 | let construct = if params.has_getter { | |
913 | let local = ¶ms.local; | |
914 | quote!(#local) | |
915 | } else { | |
916 | quote!(#this) | |
917 | }; | |
918 | ||
919 | let type_path = match variant_ident { | |
f9f354fc | 920 | Some(variant_ident) => quote!(#construct::#variant_ident), |
3b2f2976 XL |
921 | None => construct, |
922 | }; | |
923 | let expecting = match variant_ident { | |
924 | Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident), | |
925 | None => format!("struct {}", params.type_name()), | |
926 | }; | |
5869c6ff | 927 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
3b2f2976 | 928 | |
8faf50e0 | 929 | let visit_seq = Stmts(deserialize_seq( |
94222f64 | 930 | &type_path, params, fields, true, cattrs, expecting, |
8faf50e0 | 931 | )); |
3b2f2976 | 932 | |
0531ce1d XL |
933 | let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() { |
934 | deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs) | |
935 | } else { | |
936 | deserialize_struct_as_struct_visitor(&type_path, params, fields, cattrs) | |
937 | }; | |
3b2f2976 | 938 | let field_visitor = Stmts(field_visitor); |
0531ce1d | 939 | let fields_stmt = fields_stmt.map(Stmts); |
3b2f2976 XL |
940 | let visit_map = Stmts(visit_map); |
941 | ||
942 | let visitor_expr = quote! { | |
943 | __Visitor { | |
5869c6ff XL |
944 | marker: _serde::__private::PhantomData::<#this #ty_generics>, |
945 | lifetime: _serde::__private::PhantomData, | |
3b2f2976 XL |
946 | } |
947 | }; | |
948 | let dispatch = if let Some(deserializer) = deserializer { | |
949 | quote! { | |
950 | _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) | |
951 | } | |
8faf50e0 XL |
952 | } else if is_enum && cattrs.has_flatten() { |
953 | quote! { | |
954 | _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) | |
955 | } | |
3b2f2976 XL |
956 | } else if is_enum { |
957 | quote! { | |
958 | _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) | |
959 | } | |
0531ce1d XL |
960 | } else if cattrs.has_flatten() { |
961 | quote! { | |
962 | _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr) | |
963 | } | |
3b2f2976 XL |
964 | } else { |
965 | let type_name = cattrs.name().deserialize_name(); | |
966 | quote! { | |
967 | _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) | |
968 | } | |
969 | }; | |
970 | ||
ff7c6d11 | 971 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); |
3b2f2976 XL |
972 | let visitor_var = if all_skipped { |
973 | quote!(_) | |
974 | } else { | |
975 | quote!(mut __seq) | |
976 | }; | |
977 | ||
b7449926 XL |
978 | // untagged struct variants do not get a visit_seq method. The same applies to |
979 | // structs that only have a map representation. | |
0531ce1d XL |
980 | let visit_seq = match *untagged { |
981 | Untagged::No if !cattrs.has_flatten() => Some(quote! { | |
ff7c6d11 | 982 | #[inline] |
5869c6ff | 983 | fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
984 | where |
985 | __A: _serde::de::SeqAccess<#delife>, | |
ff7c6d11 XL |
986 | { |
987 | #visit_seq | |
988 | } | |
989 | }), | |
0531ce1d | 990 | _ => None, |
3b2f2976 XL |
991 | }; |
992 | ||
8faf50e0 XL |
993 | let visitor_seed = if is_enum && cattrs.has_flatten() { |
994 | Some(quote! { | |
995 | impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause { | |
996 | type Value = #this #ty_generics; | |
997 | ||
5869c6ff | 998 | fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error> |
8faf50e0 XL |
999 | where |
1000 | __D: _serde::Deserializer<'de>, | |
1001 | { | |
1002 | _serde::Deserializer::deserialize_map(__deserializer, self) | |
1003 | } | |
1004 | } | |
1005 | }) | |
1006 | } else { | |
1007 | None | |
1008 | }; | |
1009 | ||
3b2f2976 XL |
1010 | quote_block! { |
1011 | #field_visitor | |
1012 | ||
1013 | struct __Visitor #de_impl_generics #where_clause { | |
5869c6ff XL |
1014 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
1015 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
1016 | } |
1017 | ||
ea8adc8c | 1018 | impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { |
3b2f2976 XL |
1019 | type Value = #this #ty_generics; |
1020 | ||
5869c6ff XL |
1021 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
1022 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
1023 | } |
1024 | ||
1025 | #visit_seq | |
1026 | ||
1027 | #[inline] | |
5869c6ff | 1028 | fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1029 | where |
1030 | __A: _serde::de::MapAccess<#delife>, | |
3b2f2976 XL |
1031 | { |
1032 | #visit_map | |
1033 | } | |
1034 | } | |
1035 | ||
8faf50e0 XL |
1036 | #visitor_seed |
1037 | ||
3b2f2976 XL |
1038 | #fields_stmt |
1039 | ||
1040 | #dispatch | |
1041 | } | |
1042 | } | |
1043 | ||
ff7c6d11 XL |
1044 | #[cfg(feature = "deserialize_in_place")] |
1045 | fn deserialize_struct_in_place( | |
8faf50e0 | 1046 | variant_ident: Option<syn::Ident>, |
ff7c6d11 XL |
1047 | params: &Parameters, |
1048 | fields: &[Field], | |
1049 | cattrs: &attr::Container, | |
8faf50e0 | 1050 | deserializer: Option<TokenStream>, |
0531ce1d | 1051 | ) -> Option<Fragment> { |
ff7c6d11 XL |
1052 | let is_enum = variant_ident.is_some(); |
1053 | ||
0531ce1d XL |
1054 | // for now we do not support in_place deserialization for structs that |
1055 | // are represented as map. | |
1056 | if cattrs.has_flatten() { | |
1057 | return None; | |
1058 | } | |
1059 | ||
ff7c6d11 XL |
1060 | let this = ¶ms.this; |
1061 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = | |
1062 | split_with_de_lifetime(params); | |
1063 | let delife = params.borrowed.de_lifetime(); | |
1064 | ||
1065 | let expecting = match variant_ident { | |
1066 | Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident), | |
1067 | None => format!("struct {}", params.type_name()), | |
1068 | }; | |
5869c6ff | 1069 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
ff7c6d11 | 1070 | |
94222f64 | 1071 | let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting)); |
ff7c6d11 | 1072 | |
83c7162d XL |
1073 | let (field_visitor, fields_stmt, visit_map) = |
1074 | deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs); | |
0531ce1d | 1075 | |
ff7c6d11 XL |
1076 | let field_visitor = Stmts(field_visitor); |
1077 | let fields_stmt = Stmts(fields_stmt); | |
1078 | let visit_map = Stmts(visit_map); | |
1079 | ||
1080 | let visitor_expr = quote! { | |
1081 | __Visitor { | |
1082 | place: __place, | |
5869c6ff | 1083 | lifetime: _serde::__private::PhantomData, |
ff7c6d11 XL |
1084 | } |
1085 | }; | |
1086 | let dispatch = if let Some(deserializer) = deserializer { | |
1087 | quote! { | |
1088 | _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) | |
1089 | } | |
1090 | } else if is_enum { | |
1091 | quote! { | |
1092 | _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) | |
1093 | } | |
1094 | } else { | |
1095 | let type_name = cattrs.name().deserialize_name(); | |
1096 | quote! { | |
1097 | _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) | |
1098 | } | |
1099 | }; | |
1100 | ||
1101 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); | |
1102 | let visitor_var = if all_skipped { | |
1103 | quote!(_) | |
1104 | } else { | |
1105 | quote!(mut __seq) | |
1106 | }; | |
1107 | ||
0531ce1d XL |
1108 | let visit_seq = quote! { |
1109 | #[inline] | |
5869c6ff | 1110 | fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1111 | where |
1112 | __A: _serde::de::SeqAccess<#delife>, | |
0531ce1d XL |
1113 | { |
1114 | #visit_seq | |
1115 | } | |
ff7c6d11 XL |
1116 | }; |
1117 | ||
1118 | let in_place_impl_generics = de_impl_generics.in_place(); | |
1119 | let in_place_ty_generics = de_ty_generics.in_place(); | |
1120 | let place_life = place_lifetime(); | |
1121 | ||
0531ce1d | 1122 | Some(quote_block! { |
ff7c6d11 XL |
1123 | #field_visitor |
1124 | ||
1125 | struct __Visitor #in_place_impl_generics #where_clause { | |
1126 | place: &#place_life mut #this #ty_generics, | |
5869c6ff | 1127 | lifetime: _serde::__private::PhantomData<&#delife ()>, |
ff7c6d11 XL |
1128 | } |
1129 | ||
1130 | impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { | |
1131 | type Value = (); | |
1132 | ||
5869c6ff XL |
1133 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
1134 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
ff7c6d11 XL |
1135 | } |
1136 | ||
1137 | #visit_seq | |
1138 | ||
1139 | #[inline] | |
5869c6ff | 1140 | fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1141 | where |
1142 | __A: _serde::de::MapAccess<#delife>, | |
ff7c6d11 XL |
1143 | { |
1144 | #visit_map | |
1145 | } | |
1146 | } | |
1147 | ||
1148 | #fields_stmt | |
1149 | ||
1150 | #dispatch | |
0531ce1d | 1151 | }) |
ff7c6d11 XL |
1152 | } |
1153 | ||
3b2f2976 XL |
1154 | fn deserialize_enum( |
1155 | params: &Parameters, | |
1156 | variants: &[Variant], | |
1157 | cattrs: &attr::Container, | |
1158 | ) -> Fragment { | |
f9f354fc XL |
1159 | match cattrs.tag() { |
1160 | attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs), | |
1161 | attr::TagType::Internal { tag } => { | |
3b2f2976 XL |
1162 | deserialize_internally_tagged_enum(params, variants, cattrs, tag) |
1163 | } | |
f9f354fc XL |
1164 | attr::TagType::Adjacent { tag, content } => { |
1165 | deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content) | |
1166 | } | |
1167 | attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs), | |
3b2f2976 XL |
1168 | } |
1169 | } | |
1170 | ||
f9f354fc | 1171 | fn prepare_enum_variant_enum( |
3b2f2976 XL |
1172 | variants: &[Variant], |
1173 | cattrs: &attr::Container, | |
f9f354fc | 1174 | ) -> (TokenStream, Stmts) { |
f035d41b | 1175 | let mut deserialized_variants = variants |
3b2f2976 XL |
1176 | .iter() |
1177 | .enumerate() | |
f035d41b XL |
1178 | .filter(|&(_, variant)| !variant.attrs.skip_deserializing()); |
1179 | ||
1180 | let variant_names_idents: Vec<_> = deserialized_variants | |
1181 | .clone() | |
f9f354fc XL |
1182 | .map(|(i, variant)| { |
1183 | ( | |
1184 | variant.attrs.name().deserialize_name(), | |
1185 | field_i(i), | |
1186 | variant.attrs.aliases(), | |
1187 | ) | |
1188 | }) | |
3b2f2976 XL |
1189 | .collect(); |
1190 | ||
f035d41b | 1191 | let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other()); |
0731742a | 1192 | |
3b2f2976 | 1193 | let variants_stmt = { |
f9f354fc | 1194 | let variant_names = variant_names_idents.iter().map(|(name, _, _)| name); |
3b2f2976 XL |
1195 | quote! { |
1196 | const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; | |
1197 | } | |
1198 | }; | |
1199 | ||
ff7c6d11 | 1200 | let variant_visitor = Stmts(deserialize_generated_identifier( |
0531ce1d | 1201 | &variant_names_idents, |
ff7c6d11 XL |
1202 | cattrs, |
1203 | true, | |
0731742a | 1204 | other_idx, |
ff7c6d11 | 1205 | )); |
3b2f2976 | 1206 | |
f9f354fc XL |
1207 | (variants_stmt, variant_visitor) |
1208 | } | |
1209 | ||
1210 | fn deserialize_externally_tagged_enum( | |
1211 | params: &Parameters, | |
1212 | variants: &[Variant], | |
1213 | cattrs: &attr::Container, | |
1214 | ) -> Fragment { | |
1215 | let this = ¶ms.this; | |
1216 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = | |
1217 | split_with_de_lifetime(params); | |
1218 | let delife = params.borrowed.de_lifetime(); | |
1219 | ||
1220 | let type_name = cattrs.name().deserialize_name(); | |
1221 | let expecting = format!("enum {}", params.type_name()); | |
5869c6ff | 1222 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
f9f354fc XL |
1223 | |
1224 | let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); | |
1225 | ||
3b2f2976 XL |
1226 | // Match arms to extract a variant from a string |
1227 | let variant_arms = variants | |
1228 | .iter() | |
1229 | .enumerate() | |
1230 | .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) | |
ff7c6d11 XL |
1231 | .map(|(i, variant)| { |
1232 | let variant_name = field_i(i); | |
3b2f2976 | 1233 | |
ff7c6d11 | 1234 | let block = Match(deserialize_externally_tagged_variant( |
83c7162d | 1235 | params, variant, cattrs, |
ff7c6d11 | 1236 | )); |
3b2f2976 | 1237 | |
ff7c6d11 XL |
1238 | quote! { |
1239 | (__Field::#variant_name, __variant) => #block | |
1240 | } | |
1241 | }); | |
3b2f2976 XL |
1242 | |
1243 | let all_skipped = variants | |
1244 | .iter() | |
1245 | .all(|variant| variant.attrs.skip_deserializing()); | |
1246 | let match_variant = if all_skipped { | |
1247 | // This is an empty enum like `enum Impossible {}` or an enum in which | |
1248 | // all variants have `#[serde(skip_deserializing)]`. | |
1249 | quote! { | |
1250 | // FIXME: Once we drop support for Rust 1.15: | |
5869c6ff XL |
1251 | // let _serde::__private::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data); |
1252 | // _serde::__private::Err(__err) | |
1253 | _serde::__private::Result::map( | |
3b2f2976 XL |
1254 | _serde::de::EnumAccess::variant::<__Field>(__data), |
1255 | |(__impossible, _)| match __impossible {}) | |
1256 | } | |
1257 | } else { | |
1258 | quote! { | |
1259 | match try!(_serde::de::EnumAccess::variant(__data)) { | |
1260 | #(#variant_arms)* | |
1261 | } | |
1262 | } | |
1263 | }; | |
1264 | ||
1265 | quote_block! { | |
1266 | #variant_visitor | |
1267 | ||
1268 | struct __Visitor #de_impl_generics #where_clause { | |
5869c6ff XL |
1269 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
1270 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
1271 | } |
1272 | ||
ea8adc8c | 1273 | impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { |
3b2f2976 XL |
1274 | type Value = #this #ty_generics; |
1275 | ||
5869c6ff XL |
1276 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
1277 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
1278 | } |
1279 | ||
5869c6ff | 1280 | fn visit_enum<__A>(self, __data: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1281 | where |
1282 | __A: _serde::de::EnumAccess<#delife>, | |
3b2f2976 XL |
1283 | { |
1284 | #match_variant | |
1285 | } | |
1286 | } | |
1287 | ||
1288 | #variants_stmt | |
1289 | ||
f9f354fc XL |
1290 | _serde::Deserializer::deserialize_enum( |
1291 | __deserializer, | |
1292 | #type_name, | |
1293 | VARIANTS, | |
1294 | __Visitor { | |
5869c6ff XL |
1295 | marker: _serde::__private::PhantomData::<#this #ty_generics>, |
1296 | lifetime: _serde::__private::PhantomData, | |
f9f354fc XL |
1297 | }, |
1298 | ) | |
3b2f2976 XL |
1299 | } |
1300 | } | |
1301 | ||
1302 | fn deserialize_internally_tagged_enum( | |
1303 | params: &Parameters, | |
1304 | variants: &[Variant], | |
1305 | cattrs: &attr::Container, | |
1306 | tag: &str, | |
1307 | ) -> Fragment { | |
f9f354fc | 1308 | let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); |
3b2f2976 XL |
1309 | |
1310 | // Match arms to extract a variant from a string | |
ff7c6d11 XL |
1311 | let variant_arms = variants |
1312 | .iter() | |
3b2f2976 XL |
1313 | .enumerate() |
1314 | .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) | |
1315 | .map(|(i, variant)| { | |
1316 | let variant_name = field_i(i); | |
1317 | ||
1318 | let block = Match(deserialize_internally_tagged_variant( | |
1319 | params, | |
1320 | variant, | |
1321 | cattrs, | |
83c7162d | 1322 | quote! { |
5869c6ff | 1323 | _serde::__private::de::ContentDeserializer::<__D::Error>::new(__tagged.content) |
83c7162d | 1324 | }, |
3b2f2976 XL |
1325 | )); |
1326 | ||
1327 | quote! { | |
1328 | __Field::#variant_name => #block | |
1329 | } | |
1330 | }); | |
1331 | ||
5869c6ff XL |
1332 | let expecting = format!("internally tagged enum {}", params.type_name()); |
1333 | let expecting = cattrs.expecting().unwrap_or(&expecting); | |
1334 | ||
3b2f2976 XL |
1335 | quote_block! { |
1336 | #variant_visitor | |
1337 | ||
1338 | #variants_stmt | |
1339 | ||
1340 | let __tagged = try!(_serde::Deserializer::deserialize_any( | |
1341 | __deserializer, | |
5869c6ff | 1342 | _serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))); |
3b2f2976 XL |
1343 | |
1344 | match __tagged.tag { | |
1345 | #(#variant_arms)* | |
1346 | } | |
1347 | } | |
1348 | } | |
1349 | ||
1350 | fn deserialize_adjacently_tagged_enum( | |
1351 | params: &Parameters, | |
1352 | variants: &[Variant], | |
1353 | cattrs: &attr::Container, | |
1354 | tag: &str, | |
1355 | content: &str, | |
1356 | ) -> Fragment { | |
1357 | let this = ¶ms.this; | |
ff7c6d11 XL |
1358 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = |
1359 | split_with_de_lifetime(params); | |
ea8adc8c | 1360 | let delife = params.borrowed.de_lifetime(); |
3b2f2976 | 1361 | |
f9f354fc | 1362 | let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs); |
3b2f2976 | 1363 | |
0531ce1d | 1364 | let variant_arms: &Vec<_> = &variants |
3b2f2976 XL |
1365 | .iter() |
1366 | .enumerate() | |
1367 | .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) | |
ff7c6d11 XL |
1368 | .map(|(i, variant)| { |
1369 | let variant_index = field_i(i); | |
3b2f2976 | 1370 | |
ff7c6d11 XL |
1371 | let block = Match(deserialize_untagged_variant( |
1372 | params, | |
1373 | variant, | |
1374 | cattrs, | |
1375 | quote!(__deserializer), | |
1376 | )); | |
3b2f2976 | 1377 | |
ff7c6d11 XL |
1378 | quote! { |
1379 | __Field::#variant_index => #block | |
1380 | } | |
0731742a XL |
1381 | }) |
1382 | .collect(); | |
3b2f2976 XL |
1383 | |
1384 | let expecting = format!("adjacently tagged enum {}", params.type_name()); | |
5869c6ff | 1385 | let expecting = cattrs.expecting().unwrap_or(&expecting); |
3b2f2976 XL |
1386 | let type_name = cattrs.name().deserialize_name(); |
1387 | let deny_unknown_fields = cattrs.deny_unknown_fields(); | |
1388 | ||
ea8adc8c XL |
1389 | // If unknown fields are allowed, we pick the visitor that can step over |
1390 | // those. Otherwise we pick the visitor that fails on unknown keys. | |
3b2f2976 | 1391 | let field_visitor_ty = if deny_unknown_fields { |
5869c6ff | 1392 | quote! { _serde::__private::de::TagOrContentFieldVisitor } |
3b2f2976 | 1393 | } else { |
5869c6ff | 1394 | quote! { _serde::__private::de::TagContentOtherFieldVisitor } |
3b2f2976 XL |
1395 | }; |
1396 | ||
1397 | let tag_or_content = quote! { | |
1398 | #field_visitor_ty { | |
1399 | tag: #tag, | |
1400 | content: #content, | |
1401 | } | |
1402 | }; | |
1403 | ||
3b2f2976 | 1404 | let mut missing_content = quote! { |
5869c6ff | 1405 | _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content)) |
3b2f2976 | 1406 | }; |
f035d41b XL |
1407 | let mut missing_content_fallthrough = quote!(); |
1408 | let missing_content_arms = variants | |
1409 | .iter() | |
1410 | .enumerate() | |
1411 | .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) | |
1412 | .filter_map(|(i, variant)| { | |
1413 | let variant_index = field_i(i); | |
1414 | let variant_ident = &variant.ident; | |
1415 | ||
1416 | let arm = match variant.style { | |
1417 | Style::Unit => quote! { | |
5869c6ff | 1418 | _serde::__private::Ok(#this::#variant_ident) |
f035d41b XL |
1419 | }, |
1420 | Style::Newtype if variant.attrs.deserialize_with().is_none() => { | |
1421 | let span = variant.original.span(); | |
5869c6ff | 1422 | let func = quote_spanned!(span=> _serde::__private::de::missing_field); |
f035d41b XL |
1423 | quote! { |
1424 | #func(#content).map(#this::#variant_ident) | |
1425 | } | |
1426 | } | |
1427 | _ => { | |
1428 | missing_content_fallthrough = quote!(_ => #missing_content); | |
1429 | return None; | |
1430 | } | |
1431 | }; | |
ff7c6d11 | 1432 | Some(quote! { |
f035d41b | 1433 | __Field::#variant_index => #arm, |
ff7c6d11 | 1434 | }) |
f035d41b XL |
1435 | }) |
1436 | .collect::<Vec<_>>(); | |
1437 | if !missing_content_arms.is_empty() { | |
3b2f2976 XL |
1438 | missing_content = quote! { |
1439 | match __field { | |
f035d41b XL |
1440 | #(#missing_content_arms)* |
1441 | #missing_content_fallthrough | |
3b2f2976 XL |
1442 | } |
1443 | }; | |
1444 | } | |
1445 | ||
ea8adc8c | 1446 | // Advance the map by one key, returning early in case of error. |
3b2f2976 XL |
1447 | let next_key = quote! { |
1448 | try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) | |
1449 | }; | |
1450 | ||
ea8adc8c XL |
1451 | // When allowing unknown fields, we want to transparently step through keys |
1452 | // we don't care about until we find `tag`, `content`, or run out of keys. | |
3b2f2976 XL |
1453 | let next_relevant_key = if deny_unknown_fields { |
1454 | next_key | |
1455 | } else { | |
ff7c6d11 | 1456 | quote!({ |
5869c6ff XL |
1457 | let mut __rk : _serde::__private::Option<_serde::__private::de::TagOrContentField> = _serde::__private::None; |
1458 | while let _serde::__private::Some(__k) = #next_key { | |
ff7c6d11 | 1459 | match __k { |
5869c6ff | 1460 | _serde::__private::de::TagContentOtherField::Other => { |
a2a8927a | 1461 | let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); |
ff7c6d11 XL |
1462 | continue; |
1463 | }, | |
5869c6ff XL |
1464 | _serde::__private::de::TagContentOtherField::Tag => { |
1465 | __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag); | |
ff7c6d11 XL |
1466 | break; |
1467 | } | |
5869c6ff XL |
1468 | _serde::__private::de::TagContentOtherField::Content => { |
1469 | __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Content); | |
ff7c6d11 | 1470 | break; |
3b2f2976 XL |
1471 | } |
1472 | } | |
3b2f2976 | 1473 | } |
ff7c6d11 XL |
1474 | |
1475 | __rk | |
1476 | }) | |
3b2f2976 XL |
1477 | }; |
1478 | ||
ea8adc8c XL |
1479 | // Step through remaining keys, looking for duplicates of previously-seen |
1480 | // keys. When unknown fields are denied, any key that isn't a duplicate will | |
1481 | // at this point immediately produce an error. | |
3b2f2976 XL |
1482 | let visit_remaining_keys = quote! { |
1483 | match #next_relevant_key { | |
5869c6ff XL |
1484 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { |
1485 | _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) | |
3b2f2976 | 1486 | } |
5869c6ff XL |
1487 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { |
1488 | _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) | |
3b2f2976 | 1489 | } |
5869c6ff | 1490 | _serde::__private::None => _serde::__private::Ok(__ret), |
3b2f2976 XL |
1491 | } |
1492 | }; | |
1493 | ||
8faf50e0 XL |
1494 | let finish_content_then_tag = if variant_arms.is_empty() { |
1495 | quote! { | |
1496 | match try!(_serde::de::MapAccess::next_value::<__Field>(&mut __map)) {} | |
1497 | } | |
1498 | } else { | |
1499 | quote! { | |
1500 | let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) { | |
1501 | // Deserialize the buffered content now that we know the variant. | |
1502 | #(#variant_arms)* | |
1503 | }); | |
1504 | // Visit remaining keys, looking for duplicates. | |
1505 | #visit_remaining_keys | |
1506 | } | |
1507 | }; | |
1508 | ||
3b2f2976 XL |
1509 | quote_block! { |
1510 | #variant_visitor | |
1511 | ||
1512 | #variants_stmt | |
1513 | ||
1514 | struct __Seed #de_impl_generics #where_clause { | |
1515 | field: __Field, | |
5869c6ff XL |
1516 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
1517 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
1518 | } |
1519 | ||
ea8adc8c | 1520 | impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause { |
3b2f2976 XL |
1521 | type Value = #this #ty_generics; |
1522 | ||
5869c6ff | 1523 | fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error> |
8faf50e0 XL |
1524 | where |
1525 | __D: _serde::Deserializer<#delife>, | |
3b2f2976 XL |
1526 | { |
1527 | match self.field { | |
1528 | #(#variant_arms)* | |
1529 | } | |
1530 | } | |
1531 | } | |
1532 | ||
1533 | struct __Visitor #de_impl_generics #where_clause { | |
5869c6ff XL |
1534 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
1535 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
1536 | } |
1537 | ||
ea8adc8c | 1538 | impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { |
3b2f2976 XL |
1539 | type Value = #this #ty_generics; |
1540 | ||
5869c6ff XL |
1541 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
1542 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
1543 | } |
1544 | ||
5869c6ff | 1545 | fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1546 | where |
1547 | __A: _serde::de::MapAccess<#delife>, | |
3b2f2976 XL |
1548 | { |
1549 | // Visit the first relevant key. | |
1550 | match #next_relevant_key { | |
1551 | // First key is the tag. | |
5869c6ff | 1552 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { |
3b2f2976 XL |
1553 | // Parse the tag. |
1554 | let __field = try!(_serde::de::MapAccess::next_value(&mut __map)); | |
1555 | // Visit the second key. | |
1556 | match #next_relevant_key { | |
1557 | // Second key is a duplicate of the tag. | |
5869c6ff XL |
1558 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { |
1559 | _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) | |
3b2f2976 XL |
1560 | } |
1561 | // Second key is the content. | |
5869c6ff | 1562 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { |
3b2f2976 XL |
1563 | let __ret = try!(_serde::de::MapAccess::next_value_seed(&mut __map, |
1564 | __Seed { | |
1565 | field: __field, | |
5869c6ff XL |
1566 | marker: _serde::__private::PhantomData, |
1567 | lifetime: _serde::__private::PhantomData, | |
3b2f2976 XL |
1568 | })); |
1569 | // Visit remaining keys, looking for duplicates. | |
1570 | #visit_remaining_keys | |
1571 | } | |
1572 | // There is no second key; might be okay if the we have a unit variant. | |
5869c6ff | 1573 | _serde::__private::None => #missing_content |
3b2f2976 XL |
1574 | } |
1575 | } | |
1576 | // First key is the content. | |
5869c6ff | 1577 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { |
3b2f2976 | 1578 | // Buffer up the content. |
5869c6ff | 1579 | let __content = try!(_serde::de::MapAccess::next_value::<_serde::__private::de::Content>(&mut __map)); |
3b2f2976 XL |
1580 | // Visit the second key. |
1581 | match #next_relevant_key { | |
1582 | // Second key is the tag. | |
5869c6ff XL |
1583 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { |
1584 | let __deserializer = _serde::__private::de::ContentDeserializer::<__A::Error>::new(__content); | |
8faf50e0 | 1585 | #finish_content_then_tag |
3b2f2976 XL |
1586 | } |
1587 | // Second key is a duplicate of the content. | |
5869c6ff XL |
1588 | _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { |
1589 | _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) | |
3b2f2976 XL |
1590 | } |
1591 | // There is no second key. | |
5869c6ff XL |
1592 | _serde::__private::None => { |
1593 | _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) | |
3b2f2976 XL |
1594 | } |
1595 | } | |
1596 | } | |
1597 | // There is no first key. | |
5869c6ff XL |
1598 | _serde::__private::None => { |
1599 | _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) | |
3b2f2976 XL |
1600 | } |
1601 | } | |
1602 | } | |
1603 | ||
5869c6ff | 1604 | fn visit_seq<__A>(self, mut __seq: __A) -> _serde::__private::Result<Self::Value, __A::Error> |
8faf50e0 XL |
1605 | where |
1606 | __A: _serde::de::SeqAccess<#delife>, | |
3b2f2976 XL |
1607 | { |
1608 | // Visit the first element - the tag. | |
1609 | match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { | |
5869c6ff | 1610 | _serde::__private::Some(__field) => { |
3b2f2976 | 1611 | // Visit the second element - the content. |
f9f354fc XL |
1612 | match try!(_serde::de::SeqAccess::next_element_seed( |
1613 | &mut __seq, | |
1614 | __Seed { | |
1615 | field: __field, | |
5869c6ff XL |
1616 | marker: _serde::__private::PhantomData, |
1617 | lifetime: _serde::__private::PhantomData, | |
f9f354fc XL |
1618 | }, |
1619 | )) { | |
5869c6ff | 1620 | _serde::__private::Some(__ret) => _serde::__private::Ok(__ret), |
3b2f2976 | 1621 | // There is no second element. |
5869c6ff XL |
1622 | _serde::__private::None => { |
1623 | _serde::__private::Err(_serde::de::Error::invalid_length(1, &self)) | |
3b2f2976 XL |
1624 | } |
1625 | } | |
1626 | } | |
1627 | // There is no first element. | |
5869c6ff XL |
1628 | _serde::__private::None => { |
1629 | _serde::__private::Err(_serde::de::Error::invalid_length(0, &self)) | |
3b2f2976 XL |
1630 | } |
1631 | } | |
1632 | } | |
1633 | } | |
1634 | ||
1635 | const FIELDS: &'static [&'static str] = &[#tag, #content]; | |
f9f354fc XL |
1636 | _serde::Deserializer::deserialize_struct( |
1637 | __deserializer, | |
1638 | #type_name, | |
1639 | FIELDS, | |
3b2f2976 | 1640 | __Visitor { |
5869c6ff XL |
1641 | marker: _serde::__private::PhantomData::<#this #ty_generics>, |
1642 | lifetime: _serde::__private::PhantomData, | |
f9f354fc XL |
1643 | }, |
1644 | ) | |
3b2f2976 XL |
1645 | } |
1646 | } | |
1647 | ||
1648 | fn deserialize_untagged_enum( | |
1649 | params: &Parameters, | |
1650 | variants: &[Variant], | |
1651 | cattrs: &attr::Container, | |
1652 | ) -> Fragment { | |
1653 | let attempts = variants | |
1654 | .iter() | |
1655 | .filter(|variant| !variant.attrs.skip_deserializing()) | |
ff7c6d11 XL |
1656 | .map(|variant| { |
1657 | Expr(deserialize_untagged_variant( | |
3b2f2976 XL |
1658 | params, |
1659 | variant, | |
1660 | cattrs, | |
5869c6ff XL |
1661 | quote!( |
1662 | _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content) | |
1663 | ), | |
3b2f2976 | 1664 | )) |
ff7c6d11 | 1665 | }); |
3b2f2976 XL |
1666 | |
1667 | // TODO this message could be better by saving the errors from the failed | |
1668 | // attempts. The heuristic used by TOML was to count the number of fields | |
1669 | // processed before an error, and use the error that happened after the | |
1670 | // largest number of fields. I'm not sure I like that. Maybe it would be | |
1671 | // better to save all the errors and combine them into one message that | |
1672 | // explains why none of the variants matched. | |
ff7c6d11 XL |
1673 | let fallthrough_msg = format!( |
1674 | "data did not match any variant of untagged enum {}", | |
1675 | params.type_name() | |
1676 | ); | |
5869c6ff | 1677 | let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg); |
3b2f2976 XL |
1678 | |
1679 | quote_block! { | |
5869c6ff | 1680 | let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); |
3b2f2976 XL |
1681 | |
1682 | #( | |
5869c6ff XL |
1683 | if let _serde::__private::Ok(__ok) = #attempts { |
1684 | return _serde::__private::Ok(__ok); | |
3b2f2976 XL |
1685 | } |
1686 | )* | |
1687 | ||
5869c6ff | 1688 | _serde::__private::Err(_serde::de::Error::custom(#fallthrough_msg)) |
3b2f2976 XL |
1689 | } |
1690 | } | |
1691 | ||
1692 | fn deserialize_externally_tagged_variant( | |
1693 | params: &Parameters, | |
1694 | variant: &Variant, | |
1695 | cattrs: &attr::Container, | |
1696 | ) -> Fragment { | |
ea8adc8c | 1697 | if let Some(path) = variant.attrs.deserialize_with() { |
83c7162d | 1698 | let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path); |
ea8adc8c XL |
1699 | return quote_block! { |
1700 | #wrapper | |
5869c6ff | 1701 | _serde::__private::Result::map( |
ea8adc8c XL |
1702 | _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn) |
1703 | }; | |
1704 | } | |
1705 | ||
3b2f2976 XL |
1706 | let variant_ident = &variant.ident; |
1707 | ||
1708 | match variant.style { | |
1709 | Style::Unit => { | |
1710 | let this = ¶ms.this; | |
1711 | quote_block! { | |
1712 | try!(_serde::de::VariantAccess::unit_variant(__variant)); | |
5869c6ff | 1713 | _serde::__private::Ok(#this::#variant_ident) |
3b2f2976 XL |
1714 | } |
1715 | } | |
f9f354fc XL |
1716 | Style::Newtype => deserialize_externally_tagged_newtype_variant( |
1717 | variant_ident, | |
1718 | params, | |
1719 | &variant.fields[0], | |
1720 | cattrs, | |
1721 | ), | |
3b2f2976 XL |
1722 | Style::Tuple => { |
1723 | deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None) | |
1724 | } | |
ff7c6d11 XL |
1725 | Style::Struct => deserialize_struct( |
1726 | Some(variant_ident), | |
1727 | params, | |
1728 | &variant.fields, | |
1729 | cattrs, | |
1730 | None, | |
0531ce1d | 1731 | &Untagged::No, |
ff7c6d11 | 1732 | ), |
3b2f2976 XL |
1733 | } |
1734 | } | |
1735 | ||
c295e0f8 XL |
1736 | // Generates significant part of the visit_seq and visit_map bodies of visitors |
1737 | // for the variants of internally tagged enum. | |
3b2f2976 XL |
1738 | fn deserialize_internally_tagged_variant( |
1739 | params: &Parameters, | |
1740 | variant: &Variant, | |
1741 | cattrs: &attr::Container, | |
8faf50e0 | 1742 | deserializer: TokenStream, |
3b2f2976 | 1743 | ) -> Fragment { |
ea8adc8c XL |
1744 | if variant.attrs.deserialize_with().is_some() { |
1745 | return deserialize_untagged_variant(params, variant, cattrs, deserializer); | |
1746 | } | |
1747 | ||
3b2f2976 XL |
1748 | let variant_ident = &variant.ident; |
1749 | ||
f9f354fc | 1750 | match effective_style(variant) { |
3b2f2976 XL |
1751 | Style::Unit => { |
1752 | let this = ¶ms.this; | |
1753 | let type_name = params.type_name(); | |
8faf50e0 | 1754 | let variant_name = variant.ident.to_string(); |
f9f354fc XL |
1755 | let default = variant.fields.get(0).map(|field| { |
1756 | let default = Expr(expr_is_missing(field, cattrs)); | |
1757 | quote!((#default)) | |
1758 | }); | |
3b2f2976 | 1759 | quote_block! { |
5869c6ff XL |
1760 | try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); |
1761 | _serde::__private::Ok(#this::#variant_ident #default) | |
3b2f2976 XL |
1762 | } |
1763 | } | |
ff7c6d11 XL |
1764 | Style::Newtype => deserialize_untagged_newtype_variant( |
1765 | variant_ident, | |
1766 | params, | |
1767 | &variant.fields[0], | |
0531ce1d | 1768 | &deserializer, |
ff7c6d11 XL |
1769 | ), |
1770 | Style::Struct => deserialize_struct( | |
1771 | Some(variant_ident), | |
1772 | params, | |
1773 | &variant.fields, | |
1774 | cattrs, | |
1775 | Some(deserializer), | |
0531ce1d | 1776 | &Untagged::No, |
ff7c6d11 | 1777 | ), |
3b2f2976 XL |
1778 | Style::Tuple => unreachable!("checked in serde_derive_internals"), |
1779 | } | |
1780 | } | |
1781 | ||
1782 | fn deserialize_untagged_variant( | |
1783 | params: &Parameters, | |
1784 | variant: &Variant, | |
1785 | cattrs: &attr::Container, | |
8faf50e0 | 1786 | deserializer: TokenStream, |
3b2f2976 | 1787 | ) -> Fragment { |
ea8adc8c | 1788 | if let Some(path) = variant.attrs.deserialize_with() { |
c295e0f8 | 1789 | let unwrap_fn = unwrap_to_variant_closure(params, variant, false); |
ea8adc8c | 1790 | return quote_block! { |
c295e0f8 | 1791 | _serde::__private::Result::map(#path(#deserializer), #unwrap_fn) |
ea8adc8c XL |
1792 | }; |
1793 | } | |
1794 | ||
3b2f2976 XL |
1795 | let variant_ident = &variant.ident; |
1796 | ||
f9f354fc | 1797 | match effective_style(variant) { |
3b2f2976 XL |
1798 | Style::Unit => { |
1799 | let this = ¶ms.this; | |
1800 | let type_name = params.type_name(); | |
8faf50e0 | 1801 | let variant_name = variant.ident.to_string(); |
f9f354fc XL |
1802 | let default = variant.fields.get(0).map(|field| { |
1803 | let default = Expr(expr_is_missing(field, cattrs)); | |
1804 | quote!((#default)) | |
1805 | }); | |
3b2f2976 | 1806 | quote_expr! { |
8faf50e0 XL |
1807 | match _serde::Deserializer::deserialize_any( |
1808 | #deserializer, | |
5869c6ff | 1809 | _serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) |
8faf50e0 | 1810 | ) { |
5869c6ff XL |
1811 | _serde::__private::Ok(()) => _serde::__private::Ok(#this::#variant_ident #default), |
1812 | _serde::__private::Err(__err) => _serde::__private::Err(__err), | |
8faf50e0 | 1813 | } |
3b2f2976 XL |
1814 | } |
1815 | } | |
ff7c6d11 XL |
1816 | Style::Newtype => deserialize_untagged_newtype_variant( |
1817 | variant_ident, | |
1818 | params, | |
1819 | &variant.fields[0], | |
0531ce1d | 1820 | &deserializer, |
ff7c6d11 XL |
1821 | ), |
1822 | Style::Tuple => deserialize_tuple( | |
1823 | Some(variant_ident), | |
1824 | params, | |
1825 | &variant.fields, | |
1826 | cattrs, | |
1827 | Some(deserializer), | |
1828 | ), | |
1829 | Style::Struct => deserialize_struct( | |
1830 | Some(variant_ident), | |
1831 | params, | |
1832 | &variant.fields, | |
1833 | cattrs, | |
1834 | Some(deserializer), | |
0531ce1d | 1835 | &Untagged::Yes, |
ff7c6d11 | 1836 | ), |
3b2f2976 XL |
1837 | } |
1838 | } | |
1839 | ||
1840 | fn deserialize_externally_tagged_newtype_variant( | |
1841 | variant_ident: &syn::Ident, | |
1842 | params: &Parameters, | |
1843 | field: &Field, | |
f9f354fc | 1844 | cattrs: &attr::Container, |
3b2f2976 XL |
1845 | ) -> Fragment { |
1846 | let this = ¶ms.this; | |
f9f354fc XL |
1847 | |
1848 | if field.attrs.skip_deserializing() { | |
1849 | let this = ¶ms.this; | |
1850 | let default = Expr(expr_is_missing(field, cattrs)); | |
1851 | return quote_block! { | |
1852 | try!(_serde::de::VariantAccess::unit_variant(__variant)); | |
5869c6ff | 1853 | _serde::__private::Ok(#this::#variant_ident(#default)) |
f9f354fc XL |
1854 | }; |
1855 | } | |
1856 | ||
3b2f2976 XL |
1857 | match field.attrs.deserialize_with() { |
1858 | None => { | |
8faf50e0 | 1859 | let field_ty = field.ty; |
0731742a | 1860 | let span = field.original.span(); |
f9f354fc XL |
1861 | let func = |
1862 | quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>); | |
3b2f2976 | 1863 | quote_expr! { |
5869c6ff | 1864 | _serde::__private::Result::map(#func(__variant), #this::#variant_ident) |
3b2f2976 XL |
1865 | } |
1866 | } | |
1867 | Some(path) => { | |
ea8adc8c | 1868 | let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); |
3b2f2976 XL |
1869 | quote_block! { |
1870 | #wrapper | |
5869c6ff | 1871 | _serde::__private::Result::map( |
3b2f2976 XL |
1872 | _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), |
1873 | |__wrapper| #this::#variant_ident(__wrapper.value)) | |
1874 | } | |
1875 | } | |
1876 | } | |
1877 | } | |
1878 | ||
1879 | fn deserialize_untagged_newtype_variant( | |
1880 | variant_ident: &syn::Ident, | |
1881 | params: &Parameters, | |
1882 | field: &Field, | |
8faf50e0 | 1883 | deserializer: &TokenStream, |
3b2f2976 XL |
1884 | ) -> Fragment { |
1885 | let this = ¶ms.this; | |
8faf50e0 | 1886 | let field_ty = field.ty; |
3b2f2976 XL |
1887 | match field.attrs.deserialize_with() { |
1888 | None => { | |
0731742a XL |
1889 | let span = field.original.span(); |
1890 | let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); | |
3b2f2976 | 1891 | quote_expr! { |
5869c6ff | 1892 | _serde::__private::Result::map(#func(#deserializer), #this::#variant_ident) |
3b2f2976 XL |
1893 | } |
1894 | } | |
1895 | Some(path) => { | |
3b2f2976 | 1896 | quote_block! { |
5869c6ff XL |
1897 | let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer); |
1898 | _serde::__private::Result::map(__value, #this::#variant_ident) | |
3b2f2976 XL |
1899 | } |
1900 | } | |
1901 | } | |
1902 | } | |
1903 | ||
1904 | fn deserialize_generated_identifier( | |
f9f354fc | 1905 | fields: &[(String, Ident, Vec<String>)], |
3b2f2976 | 1906 | cattrs: &attr::Container, |
83c7162d | 1907 | is_variant: bool, |
0731742a | 1908 | other_idx: Option<usize>, |
3b2f2976 XL |
1909 | ) -> Fragment { |
1910 | let this = quote!(__Field); | |
f9f354fc | 1911 | let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect(); |
3b2f2976 | 1912 | |
8faf50e0 | 1913 | let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() { |
5869c6ff XL |
1914 | let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),); |
1915 | let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value))); | |
0531ce1d | 1916 | (Some(ignore_variant), Some(fallthrough)) |
0731742a XL |
1917 | } else if let Some(other_idx) = other_idx { |
1918 | let ignore_variant = fields[other_idx].1.clone(); | |
5869c6ff | 1919 | let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant)); |
0731742a | 1920 | (None, Some(fallthrough)) |
0531ce1d | 1921 | } else if is_variant || cattrs.deny_unknown_fields() { |
3b2f2976 XL |
1922 | (None, None) |
1923 | } else { | |
1924 | let ignore_variant = quote!(__ignore,); | |
5869c6ff | 1925 | let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore)); |
3b2f2976 XL |
1926 | (Some(ignore_variant), Some(fallthrough)) |
1927 | }; | |
1928 | ||
ff7c6d11 | 1929 | let visitor_impl = Stmts(deserialize_identifier( |
0531ce1d XL |
1930 | &this, |
1931 | fields, | |
ff7c6d11 XL |
1932 | is_variant, |
1933 | fallthrough, | |
5869c6ff | 1934 | None, |
8faf50e0 | 1935 | !is_variant && cattrs.has_flatten(), |
5869c6ff | 1936 | None, |
ff7c6d11 | 1937 | )); |
3b2f2976 | 1938 | |
8faf50e0 | 1939 | let lifetime = if !is_variant && cattrs.has_flatten() { |
0531ce1d XL |
1940 | Some(quote!(<'de>)) |
1941 | } else { | |
1942 | None | |
1943 | }; | |
1944 | ||
3b2f2976 XL |
1945 | quote_block! { |
1946 | #[allow(non_camel_case_types)] | |
0531ce1d | 1947 | enum __Field #lifetime { |
3b2f2976 XL |
1948 | #(#field_idents,)* |
1949 | #ignore_variant | |
1950 | } | |
1951 | ||
1952 | struct __FieldVisitor; | |
1953 | ||
1954 | impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { | |
0531ce1d | 1955 | type Value = __Field #lifetime; |
3b2f2976 XL |
1956 | |
1957 | #visitor_impl | |
1958 | } | |
1959 | ||
0531ce1d | 1960 | impl<'de> _serde::Deserialize<'de> for __Field #lifetime { |
3b2f2976 | 1961 | #[inline] |
5869c6ff | 1962 | fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error> |
8faf50e0 XL |
1963 | where |
1964 | __D: _serde::Deserializer<'de>, | |
3b2f2976 XL |
1965 | { |
1966 | _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) | |
1967 | } | |
1968 | } | |
1969 | } | |
1970 | } | |
1971 | ||
5869c6ff XL |
1972 | // Generates `Deserialize::deserialize` body for an enum with |
1973 | // `serde(field_identifier)` or `serde(variant_identifier)` attribute. | |
3b2f2976 XL |
1974 | fn deserialize_custom_identifier( |
1975 | params: &Parameters, | |
1976 | variants: &[Variant], | |
1977 | cattrs: &attr::Container, | |
1978 | ) -> Fragment { | |
1979 | let is_variant = match cattrs.identifier() { | |
1980 | attr::Identifier::Variant => true, | |
1981 | attr::Identifier::Field => false, | |
1982 | attr::Identifier::No => unreachable!(), | |
1983 | }; | |
1984 | ||
1985 | let this = ¶ms.this; | |
1986 | let this = quote!(#this); | |
1987 | ||
5869c6ff | 1988 | let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() { |
3b2f2976 XL |
1989 | let last_ident = &last.ident; |
1990 | if last.attrs.other() { | |
5869c6ff XL |
1991 | // Process `serde(other)` attribute. It would always be found on the |
1992 | // last variant (checked in `check_identifier`), so all preceding | |
1993 | // are ordinary variants. | |
3b2f2976 | 1994 | let ordinary = &variants[..variants.len() - 1]; |
5869c6ff XL |
1995 | let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident)); |
1996 | (ordinary, Some(fallthrough), None) | |
3b2f2976 XL |
1997 | } else if let Style::Newtype = last.style { |
1998 | let ordinary = &variants[..variants.len() - 1]; | |
5869c6ff XL |
1999 | let fallthrough = |value| { |
2000 | quote! { | |
2001 | _serde::__private::Result::map( | |
2002 | _serde::Deserialize::deserialize( | |
2003 | _serde::__private::de::IdentifierDeserializer::from(#value) | |
2004 | ), | |
2005 | #this::#last_ident) | |
2006 | } | |
3b2f2976 | 2007 | }; |
5869c6ff XL |
2008 | ( |
2009 | ordinary, | |
2010 | Some(fallthrough(quote!(__value))), | |
2011 | Some(fallthrough(quote!(_serde::__private::de::Borrowed( | |
2012 | __value | |
2013 | )))), | |
2014 | ) | |
3b2f2976 | 2015 | } else { |
5869c6ff | 2016 | (variants, None, None) |
3b2f2976 XL |
2017 | } |
2018 | } else { | |
5869c6ff | 2019 | (variants, None, None) |
3b2f2976 XL |
2020 | }; |
2021 | ||
2022 | let names_idents: Vec<_> = ordinary | |
2023 | .iter() | |
8faf50e0 XL |
2024 | .map(|variant| { |
2025 | ( | |
2026 | variant.attrs.name().deserialize_name(), | |
2027 | variant.ident.clone(), | |
f9f354fc | 2028 | variant.attrs.aliases(), |
8faf50e0 | 2029 | ) |
0731742a XL |
2030 | }) |
2031 | .collect(); | |
3b2f2976 | 2032 | |
f9f354fc | 2033 | let names = names_idents.iter().map(|(name, _, _)| name); |
3b2f2976 XL |
2034 | |
2035 | let names_const = if fallthrough.is_some() { | |
2036 | None | |
2037 | } else if is_variant { | |
2038 | let variants = quote! { | |
2039 | const VARIANTS: &'static [&'static str] = &[ #(#names),* ]; | |
2040 | }; | |
2041 | Some(variants) | |
2042 | } else { | |
2043 | let fields = quote! { | |
2044 | const FIELDS: &'static [&'static str] = &[ #(#names),* ]; | |
2045 | }; | |
2046 | Some(fields) | |
2047 | }; | |
2048 | ||
ff7c6d11 XL |
2049 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = |
2050 | split_with_de_lifetime(params); | |
ea8adc8c | 2051 | let delife = params.borrowed.de_lifetime(); |
ff7c6d11 | 2052 | let visitor_impl = Stmts(deserialize_identifier( |
0531ce1d | 2053 | &this, |
ff7c6d11 XL |
2054 | &names_idents, |
2055 | is_variant, | |
2056 | fallthrough, | |
5869c6ff | 2057 | fallthrough_borrowed, |
0531ce1d | 2058 | false, |
5869c6ff | 2059 | cattrs.expecting(), |
ff7c6d11 | 2060 | )); |
3b2f2976 XL |
2061 | |
2062 | quote_block! { | |
2063 | #names_const | |
2064 | ||
2065 | struct __FieldVisitor #de_impl_generics #where_clause { | |
5869c6ff XL |
2066 | marker: _serde::__private::PhantomData<#this #ty_generics>, |
2067 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
2068 | } |
2069 | ||
ea8adc8c | 2070 | impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause { |
3b2f2976 XL |
2071 | type Value = #this #ty_generics; |
2072 | ||
2073 | #visitor_impl | |
2074 | } | |
2075 | ||
2076 | let __visitor = __FieldVisitor { | |
5869c6ff XL |
2077 | marker: _serde::__private::PhantomData::<#this #ty_generics>, |
2078 | lifetime: _serde::__private::PhantomData, | |
3b2f2976 XL |
2079 | }; |
2080 | _serde::Deserializer::deserialize_identifier(__deserializer, __visitor) | |
2081 | } | |
2082 | } | |
2083 | ||
2084 | fn deserialize_identifier( | |
8faf50e0 | 2085 | this: &TokenStream, |
f9f354fc | 2086 | fields: &[(String, Ident, Vec<String>)], |
3b2f2976 | 2087 | is_variant: bool, |
8faf50e0 | 2088 | fallthrough: Option<TokenStream>, |
5869c6ff | 2089 | fallthrough_borrowed: Option<TokenStream>, |
83c7162d | 2090 | collect_other_fields: bool, |
5869c6ff | 2091 | expecting: Option<&str>, |
3b2f2976 | 2092 | ) -> Fragment { |
f9f354fc XL |
2093 | let mut flat_fields = Vec::new(); |
2094 | for (_, ident, aliases) in fields { | |
94222f64 | 2095 | flat_fields.extend(aliases.iter().map(|alias| (alias, ident))); |
f9f354fc XL |
2096 | } |
2097 | ||
5869c6ff XL |
2098 | let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect(); |
2099 | let field_bytes: &Vec<_> = &flat_fields | |
83c7162d | 2100 | .iter() |
5869c6ff XL |
2101 | .map(|(name, _)| Literal::byte_string(name.as_bytes())) |
2102 | .collect(); | |
3b2f2976 | 2103 | |
f9f354fc XL |
2104 | let constructors: &Vec<_> = &flat_fields |
2105 | .iter() | |
2106 | .map(|(_, ident)| quote!(#this::#ident)) | |
2107 | .collect(); | |
2108 | let main_constructors: &Vec<_> = &fields | |
ff7c6d11 | 2109 | .iter() |
f9f354fc | 2110 | .map(|(_, ident, _)| quote!(#this::#ident)) |
ff7c6d11 | 2111 | .collect(); |
3b2f2976 | 2112 | |
5869c6ff | 2113 | let expecting = expecting.unwrap_or(if is_variant { |
3b2f2976 XL |
2114 | "variant identifier" |
2115 | } else { | |
2116 | "field identifier" | |
5869c6ff | 2117 | }); |
3b2f2976 | 2118 | |
ff7c6d11 | 2119 | let index_expecting = if is_variant { "variant" } else { "field" }; |
ea8adc8c | 2120 | |
83c7162d XL |
2121 | let bytes_to_str = if fallthrough.is_some() || collect_other_fields { |
2122 | None | |
2123 | } else { | |
2124 | Some(quote! { | |
5869c6ff | 2125 | let __value = &_serde::__private::from_utf8_lossy(__value); |
83c7162d XL |
2126 | }) |
2127 | }; | |
2128 | ||
2129 | let ( | |
2130 | value_as_str_content, | |
2131 | value_as_borrowed_str_content, | |
2132 | value_as_bytes_content, | |
2133 | value_as_borrowed_bytes_content, | |
8faf50e0 | 2134 | ) = if collect_other_fields { |
83c7162d XL |
2135 | ( |
2136 | Some(quote! { | |
5869c6ff | 2137 | let __value = _serde::__private::de::Content::String(_serde::__private::ToString::to_string(__value)); |
83c7162d XL |
2138 | }), |
2139 | Some(quote! { | |
5869c6ff | 2140 | let __value = _serde::__private::de::Content::Str(__value); |
83c7162d XL |
2141 | }), |
2142 | Some(quote! { | |
5869c6ff | 2143 | let __value = _serde::__private::de::Content::ByteBuf(__value.to_vec()); |
83c7162d XL |
2144 | }), |
2145 | Some(quote! { | |
5869c6ff | 2146 | let __value = _serde::__private::de::Content::Bytes(__value); |
83c7162d XL |
2147 | }), |
2148 | ) | |
8faf50e0 XL |
2149 | } else { |
2150 | (None, None, None, None) | |
83c7162d XL |
2151 | }; |
2152 | ||
5869c6ff XL |
2153 | let fallthrough_arm_tokens; |
2154 | let fallthrough_arm = if let Some(fallthrough) = &fallthrough { | |
83c7162d XL |
2155 | fallthrough |
2156 | } else if is_variant { | |
5869c6ff XL |
2157 | fallthrough_arm_tokens = quote! { |
2158 | _serde::__private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) | |
2159 | }; | |
2160 | &fallthrough_arm_tokens | |
83c7162d | 2161 | } else { |
5869c6ff XL |
2162 | fallthrough_arm_tokens = quote! { |
2163 | _serde::__private::Err(_serde::de::Error::unknown_field(__value, FIELDS)) | |
2164 | }; | |
2165 | &fallthrough_arm_tokens | |
2166 | }; | |
2167 | ||
2168 | let u64_fallthrough_arm_tokens; | |
2169 | let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough { | |
2170 | fallthrough | |
2171 | } else { | |
2172 | let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); | |
2173 | u64_fallthrough_arm_tokens = quote! { | |
2174 | _serde::__private::Err(_serde::de::Error::invalid_value( | |
2175 | _serde::de::Unexpected::Unsigned(__value), | |
2176 | &#fallthrough_msg, | |
2177 | )) | |
2178 | }; | |
2179 | &u64_fallthrough_arm_tokens | |
83c7162d XL |
2180 | }; |
2181 | ||
8faf50e0 | 2182 | let variant_indices = 0_u64..; |
0531ce1d | 2183 | let visit_other = if collect_other_fields { |
83c7162d | 2184 | quote! { |
5869c6ff | 2185 | fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2186 | where |
2187 | __E: _serde::de::Error, | |
0531ce1d | 2188 | { |
5869c6ff | 2189 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Bool(__value))) |
ea8adc8c | 2190 | } |
0531ce1d | 2191 | |
5869c6ff | 2192 | fn visit_i8<__E>(self, __value: i8) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2193 | where |
2194 | __E: _serde::de::Error, | |
0531ce1d | 2195 | { |
5869c6ff | 2196 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I8(__value))) |
0531ce1d XL |
2197 | } |
2198 | ||
5869c6ff | 2199 | fn visit_i16<__E>(self, __value: i16) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2200 | where |
2201 | __E: _serde::de::Error, | |
0531ce1d | 2202 | { |
5869c6ff | 2203 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I16(__value))) |
0531ce1d XL |
2204 | } |
2205 | ||
5869c6ff | 2206 | fn visit_i32<__E>(self, __value: i32) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2207 | where |
2208 | __E: _serde::de::Error, | |
0531ce1d | 2209 | { |
5869c6ff | 2210 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I32(__value))) |
0531ce1d XL |
2211 | } |
2212 | ||
5869c6ff | 2213 | fn visit_i64<__E>(self, __value: i64) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2214 | where |
2215 | __E: _serde::de::Error, | |
0531ce1d | 2216 | { |
5869c6ff | 2217 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I64(__value))) |
0531ce1d XL |
2218 | } |
2219 | ||
5869c6ff | 2220 | fn visit_u8<__E>(self, __value: u8) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2221 | where |
2222 | __E: _serde::de::Error, | |
0531ce1d | 2223 | { |
5869c6ff | 2224 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U8(__value))) |
0531ce1d XL |
2225 | } |
2226 | ||
5869c6ff | 2227 | fn visit_u16<__E>(self, __value: u16) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2228 | where |
2229 | __E: _serde::de::Error, | |
0531ce1d | 2230 | { |
5869c6ff | 2231 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U16(__value))) |
0531ce1d XL |
2232 | } |
2233 | ||
5869c6ff | 2234 | fn visit_u32<__E>(self, __value: u32) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2235 | where |
2236 | __E: _serde::de::Error, | |
0531ce1d | 2237 | { |
5869c6ff | 2238 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U32(__value))) |
0531ce1d XL |
2239 | } |
2240 | ||
5869c6ff | 2241 | fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2242 | where |
2243 | __E: _serde::de::Error, | |
0531ce1d | 2244 | { |
5869c6ff | 2245 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U64(__value))) |
0531ce1d XL |
2246 | } |
2247 | ||
5869c6ff | 2248 | fn visit_f32<__E>(self, __value: f32) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2249 | where |
2250 | __E: _serde::de::Error, | |
0531ce1d | 2251 | { |
5869c6ff | 2252 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F32(__value))) |
0531ce1d XL |
2253 | } |
2254 | ||
5869c6ff | 2255 | fn visit_f64<__E>(self, __value: f64) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2256 | where |
2257 | __E: _serde::de::Error, | |
0531ce1d | 2258 | { |
5869c6ff | 2259 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F64(__value))) |
0531ce1d XL |
2260 | } |
2261 | ||
5869c6ff | 2262 | fn visit_char<__E>(self, __value: char) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2263 | where |
2264 | __E: _serde::de::Error, | |
0531ce1d | 2265 | { |
5869c6ff | 2266 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Char(__value))) |
0531ce1d XL |
2267 | } |
2268 | ||
5869c6ff | 2269 | fn visit_unit<__E>(self) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2270 | where |
2271 | __E: _serde::de::Error, | |
0531ce1d | 2272 | { |
5869c6ff | 2273 | _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Unit)) |
0531ce1d | 2274 | } |
5869c6ff XL |
2275 | } |
2276 | } else { | |
2277 | quote! { | |
2278 | fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E> | |
8faf50e0 XL |
2279 | where |
2280 | __E: _serde::de::Error, | |
83c7162d XL |
2281 | { |
2282 | match __value { | |
2283 | #( | |
5869c6ff | 2284 | #variant_indices => _serde::__private::Ok(#main_constructors), |
83c7162d | 2285 | )* |
5869c6ff | 2286 | _ => #u64_fallthrough_arm, |
83c7162d XL |
2287 | } |
2288 | } | |
5869c6ff XL |
2289 | } |
2290 | }; | |
83c7162d | 2291 | |
5869c6ff | 2292 | let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields { |
94222f64 | 2293 | let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm); |
5869c6ff XL |
2294 | Some(quote! { |
2295 | fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E> | |
8faf50e0 XL |
2296 | where |
2297 | __E: _serde::de::Error, | |
83c7162d XL |
2298 | { |
2299 | match __value { | |
2300 | #( | |
5869c6ff | 2301 | #field_strs => _serde::__private::Ok(#constructors), |
83c7162d XL |
2302 | )* |
2303 | _ => { | |
5869c6ff XL |
2304 | #value_as_borrowed_str_content |
2305 | #fallthrough_borrowed_arm | |
83c7162d XL |
2306 | } |
2307 | } | |
2308 | } | |
5869c6ff XL |
2309 | |
2310 | fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::__private::Result<Self::Value, __E> | |
8faf50e0 XL |
2311 | where |
2312 | __E: _serde::de::Error, | |
0531ce1d XL |
2313 | { |
2314 | match __value { | |
2315 | #( | |
5869c6ff | 2316 | #field_bytes => _serde::__private::Ok(#constructors), |
0531ce1d | 2317 | )* |
5869c6ff XL |
2318 | _ => { |
2319 | #bytes_to_str | |
2320 | #value_as_borrowed_bytes_content | |
2321 | #fallthrough_borrowed_arm | |
2322 | } | |
0531ce1d XL |
2323 | } |
2324 | } | |
5869c6ff XL |
2325 | }) |
2326 | } else { | |
2327 | None | |
3b2f2976 XL |
2328 | }; |
2329 | ||
2330 | quote_block! { | |
5869c6ff XL |
2331 | fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { |
2332 | _serde::__private::Formatter::write_str(__formatter, #expecting) | |
3b2f2976 XL |
2333 | } |
2334 | ||
0531ce1d | 2335 | #visit_other |
3b2f2976 | 2336 | |
5869c6ff | 2337 | fn visit_str<__E>(self, __value: &str) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2338 | where |
2339 | __E: _serde::de::Error, | |
3b2f2976 XL |
2340 | { |
2341 | match __value { | |
2342 | #( | |
5869c6ff | 2343 | #field_strs => _serde::__private::Ok(#constructors), |
3b2f2976 | 2344 | )* |
0531ce1d XL |
2345 | _ => { |
2346 | #value_as_str_content | |
2347 | #fallthrough_arm | |
2348 | } | |
2349 | } | |
2350 | } | |
2351 | ||
5869c6ff | 2352 | fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::__private::Result<Self::Value, __E> |
8faf50e0 XL |
2353 | where |
2354 | __E: _serde::de::Error, | |
3b2f2976 XL |
2355 | { |
2356 | match __value { | |
2357 | #( | |
5869c6ff | 2358 | #field_bytes => _serde::__private::Ok(#constructors), |
3b2f2976 XL |
2359 | )* |
2360 | _ => { | |
2361 | #bytes_to_str | |
0531ce1d | 2362 | #value_as_bytes_content |
3b2f2976 XL |
2363 | #fallthrough_arm |
2364 | } | |
2365 | } | |
2366 | } | |
5869c6ff XL |
2367 | |
2368 | #visit_borrowed | |
3b2f2976 XL |
2369 | } |
2370 | } | |
2371 | ||
0531ce1d | 2372 | fn deserialize_struct_as_struct_visitor( |
8faf50e0 | 2373 | struct_path: &TokenStream, |
3b2f2976 XL |
2374 | params: &Parameters, |
2375 | fields: &[Field], | |
2376 | cattrs: &attr::Container, | |
0531ce1d XL |
2377 | ) -> (Fragment, Option<Fragment>, Fragment) { |
2378 | assert!(!cattrs.has_flatten()); | |
2379 | ||
3b2f2976 XL |
2380 | let field_names_idents: Vec<_> = fields |
2381 | .iter() | |
2382 | .enumerate() | |
2383 | .filter(|&(_, field)| !field.attrs.skip_deserializing()) | |
f9f354fc XL |
2384 | .map(|(i, field)| { |
2385 | ( | |
2386 | field.attrs.name().deserialize_name(), | |
2387 | field_i(i), | |
2388 | field.attrs.aliases(), | |
2389 | ) | |
2390 | }) | |
3b2f2976 XL |
2391 | .collect(); |
2392 | ||
2393 | let fields_stmt = { | |
f9f354fc | 2394 | let field_names = field_names_idents.iter().map(|(name, _, _)| name); |
3b2f2976 XL |
2395 | quote_block! { |
2396 | const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; | |
2397 | } | |
2398 | }; | |
2399 | ||
0731742a | 2400 | let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); |
3b2f2976 XL |
2401 | |
2402 | let visit_map = deserialize_map(struct_path, params, fields, cattrs); | |
2403 | ||
0531ce1d XL |
2404 | (field_visitor, Some(fields_stmt), visit_map) |
2405 | } | |
2406 | ||
2407 | fn deserialize_struct_as_map_visitor( | |
8faf50e0 | 2408 | struct_path: &TokenStream, |
0531ce1d XL |
2409 | params: &Parameters, |
2410 | fields: &[Field], | |
2411 | cattrs: &attr::Container, | |
2412 | ) -> (Fragment, Option<Fragment>, Fragment) { | |
2413 | let field_names_idents: Vec<_> = fields | |
2414 | .iter() | |
2415 | .enumerate() | |
2416 | .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) | |
f9f354fc XL |
2417 | .map(|(i, field)| { |
2418 | ( | |
2419 | field.attrs.name().deserialize_name(), | |
2420 | field_i(i), | |
2421 | field.attrs.aliases(), | |
2422 | ) | |
2423 | }) | |
0531ce1d XL |
2424 | .collect(); |
2425 | ||
0731742a | 2426 | let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); |
0531ce1d XL |
2427 | |
2428 | let visit_map = deserialize_map(struct_path, params, fields, cattrs); | |
2429 | ||
2430 | (field_visitor, None, visit_map) | |
3b2f2976 XL |
2431 | } |
2432 | ||
2433 | fn deserialize_map( | |
8faf50e0 | 2434 | struct_path: &TokenStream, |
3b2f2976 XL |
2435 | params: &Parameters, |
2436 | fields: &[Field], | |
2437 | cattrs: &attr::Container, | |
2438 | ) -> Fragment { | |
2439 | // Create the field names for the fields. | |
2440 | let fields_names: Vec<_> = fields | |
2441 | .iter() | |
2442 | .enumerate() | |
2443 | .map(|(i, field)| (field, field_i(i))) | |
2444 | .collect(); | |
2445 | ||
2446 | // Declare each field that will be deserialized. | |
2447 | let let_values = fields_names | |
2448 | .iter() | |
0531ce1d | 2449 | .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) |
f9f354fc | 2450 | .map(|(field, name)| { |
8faf50e0 | 2451 | let field_ty = field.ty; |
ff7c6d11 | 2452 | quote! { |
5869c6ff | 2453 | let mut #name: _serde::__private::Option<#field_ty> = _serde::__private::None; |
ff7c6d11 XL |
2454 | } |
2455 | }); | |
3b2f2976 | 2456 | |
0531ce1d XL |
2457 | // Collect contents for flatten fields into a buffer |
2458 | let let_collect = if cattrs.has_flatten() { | |
2459 | Some(quote! { | |
5869c6ff XL |
2460 | let mut __collect = _serde::__private::Vec::<_serde::__private::Option<( |
2461 | _serde::__private::de::Content, | |
2462 | _serde::__private::de::Content | |
0531ce1d XL |
2463 | )>>::new(); |
2464 | }) | |
2465 | } else { | |
2466 | None | |
2467 | }; | |
2468 | ||
3b2f2976 | 2469 | // Match arms to extract a value for a field. |
ff7c6d11 XL |
2470 | let value_arms = fields_names |
2471 | .iter() | |
0531ce1d | 2472 | .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) |
f9f354fc | 2473 | .map(|(field, name)| { |
3b2f2976 XL |
2474 | let deser_name = field.attrs.name().deserialize_name(); |
2475 | ||
2476 | let visit = match field.attrs.deserialize_with() { | |
2477 | None => { | |
8faf50e0 | 2478 | let field_ty = field.ty; |
83c7162d XL |
2479 | let span = field.original.span(); |
2480 | let func = | |
2481 | quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>); | |
3b2f2976 | 2482 | quote! { |
0531ce1d | 2483 | try!(#func(&mut __map)) |
3b2f2976 XL |
2484 | } |
2485 | } | |
2486 | Some(path) => { | |
ff7c6d11 | 2487 | let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); |
3b2f2976 XL |
2488 | quote!({ |
2489 | #wrapper | |
f9f354fc | 2490 | match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { |
5869c6ff XL |
2491 | _serde::__private::Ok(__wrapper) => __wrapper.value, |
2492 | _serde::__private::Err(__err) => { | |
2493 | return _serde::__private::Err(__err); | |
f9f354fc XL |
2494 | } |
2495 | } | |
3b2f2976 XL |
2496 | }) |
2497 | } | |
2498 | }; | |
2499 | quote! { | |
2500 | __Field::#name => { | |
5869c6ff XL |
2501 | if _serde::__private::Option::is_some(&#name) { |
2502 | return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); | |
3b2f2976 | 2503 | } |
5869c6ff | 2504 | #name = _serde::__private::Some(#visit); |
3b2f2976 XL |
2505 | } |
2506 | } | |
2507 | }); | |
2508 | ||
2509 | // Visit ignored values to consume them | |
0531ce1d XL |
2510 | let ignored_arm = if cattrs.has_flatten() { |
2511 | Some(quote! { | |
2512 | __Field::__other(__name) => { | |
5869c6ff | 2513 | __collect.push(_serde::__private::Some(( |
0531ce1d XL |
2514 | __name, |
2515 | try!(_serde::de::MapAccess::next_value(&mut __map))))); | |
2516 | } | |
2517 | }) | |
2518 | } else if cattrs.deny_unknown_fields() { | |
3b2f2976 XL |
2519 | None |
2520 | } else { | |
2521 | Some(quote! { | |
2522 | _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } | |
2523 | }) | |
2524 | }; | |
2525 | ||
ff7c6d11 | 2526 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); |
3b2f2976 XL |
2527 | let match_keys = if cattrs.deny_unknown_fields() && all_skipped { |
2528 | quote! { | |
2529 | // FIXME: Once we drop support for Rust 1.15: | |
5869c6ff XL |
2530 | // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); |
2531 | _serde::__private::Option::map( | |
3b2f2976 XL |
2532 | try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), |
2533 | |__impossible| match __impossible {}); | |
2534 | } | |
2535 | } else { | |
2536 | quote! { | |
5869c6ff | 2537 | while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { |
3b2f2976 XL |
2538 | match __key { |
2539 | #(#value_arms)* | |
2540 | #ignored_arm | |
2541 | } | |
2542 | } | |
2543 | } | |
2544 | }; | |
2545 | ||
2546 | let extract_values = fields_names | |
2547 | .iter() | |
0531ce1d | 2548 | .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) |
f9f354fc | 2549 | .map(|(field, name)| { |
0531ce1d | 2550 | let missing_expr = Match(expr_is_missing(field, cattrs)); |
3b2f2976 | 2551 | |
ff7c6d11 XL |
2552 | quote! { |
2553 | let #name = match #name { | |
5869c6ff XL |
2554 | _serde::__private::Some(#name) => #name, |
2555 | _serde::__private::None => #missing_expr | |
ff7c6d11 XL |
2556 | }; |
2557 | } | |
2558 | }); | |
3b2f2976 | 2559 | |
0531ce1d XL |
2560 | let extract_collected = fields_names |
2561 | .iter() | |
f9f354fc XL |
2562 | .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing()) |
2563 | .map(|(field, name)| { | |
0531ce1d | 2564 | let field_ty = field.ty; |
8faf50e0 | 2565 | let func = match field.attrs.deserialize_with() { |
0731742a XL |
2566 | None => { |
2567 | let span = field.original.span(); | |
2568 | quote_spanned!(span=> _serde::de::Deserialize::deserialize) | |
f9f354fc | 2569 | } |
8faf50e0 XL |
2570 | Some(path) => quote!(#path), |
2571 | }; | |
0531ce1d | 2572 | quote! { |
8faf50e0 | 2573 | let #name: #field_ty = try!(#func( |
5869c6ff | 2574 | _serde::__private::de::FlatMapDeserializer( |
0531ce1d | 2575 | &mut __collect, |
5869c6ff | 2576 | _serde::__private::PhantomData))); |
0531ce1d XL |
2577 | } |
2578 | }); | |
2579 | ||
2580 | let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() { | |
2581 | Some(quote! { | |
5869c6ff XL |
2582 | if let _serde::__private::Some(_serde::__private::Some((__key, _))) = |
2583 | __collect.into_iter().filter(_serde::__private::Option::is_some).next() | |
f9f354fc | 2584 | { |
5869c6ff XL |
2585 | if let _serde::__private::Some(__key) = __key.as_str() { |
2586 | return _serde::__private::Err( | |
0531ce1d XL |
2587 | _serde::de::Error::custom(format_args!("unknown field `{}`", &__key))); |
2588 | } else { | |
5869c6ff | 2589 | return _serde::__private::Err( |
0531ce1d XL |
2590 | _serde::de::Error::custom(format_args!("unexpected map key"))); |
2591 | } | |
2592 | } | |
2593 | }) | |
2594 | } else { | |
2595 | None | |
2596 | }; | |
2597 | ||
f9f354fc | 2598 | let result = fields_names.iter().map(|(field, name)| { |
8faf50e0 | 2599 | let member = &field.member; |
ff7c6d11 | 2600 | if field.attrs.skip_deserializing() { |
0531ce1d | 2601 | let value = Expr(expr_is_missing(field, cattrs)); |
8faf50e0 | 2602 | quote!(#member: #value) |
ff7c6d11 | 2603 | } else { |
8faf50e0 | 2604 | quote!(#member: #name) |
ff7c6d11 XL |
2605 | } |
2606 | }); | |
3b2f2976 | 2607 | |
f9f354fc | 2608 | let let_default = match cattrs.default() { |
ff7c6d11 | 2609 | attr::Default::Default => Some(quote!( |
5869c6ff | 2610 | let __default: Self::Value = _serde::__private::Default::default(); |
ff7c6d11 | 2611 | )), |
f9f354fc | 2612 | attr::Default::Path(path) => Some(quote!( |
ff7c6d11 XL |
2613 | let __default: Self::Value = #path(); |
2614 | )), | |
3b2f2976 XL |
2615 | attr::Default::None => { |
2616 | // We don't need the default value, to prevent an unused variable warning | |
2617 | // we'll leave the line empty. | |
2618 | None | |
2619 | } | |
2620 | }; | |
2621 | ||
8faf50e0 | 2622 | let mut result = quote!(#struct_path { #(#result),* }); |
3b2f2976 XL |
2623 | if params.has_getter { |
2624 | let this = ¶ms.this; | |
2625 | result = quote! { | |
5869c6ff | 2626 | _serde::__private::Into::<#this>::into(#result) |
3b2f2976 XL |
2627 | }; |
2628 | } | |
2629 | ||
2630 | quote_block! { | |
2631 | #(#let_values)* | |
2632 | ||
0531ce1d XL |
2633 | #let_collect |
2634 | ||
3b2f2976 XL |
2635 | #match_keys |
2636 | ||
2637 | #let_default | |
2638 | ||
2639 | #(#extract_values)* | |
2640 | ||
0531ce1d XL |
2641 | #(#extract_collected)* |
2642 | ||
2643 | #collected_deny_unknown_fields | |
2644 | ||
5869c6ff | 2645 | _serde::__private::Ok(#result) |
3b2f2976 XL |
2646 | } |
2647 | } | |
2648 | ||
ff7c6d11 | 2649 | #[cfg(feature = "deserialize_in_place")] |
0531ce1d | 2650 | fn deserialize_struct_as_struct_in_place_visitor( |
ff7c6d11 XL |
2651 | params: &Parameters, |
2652 | fields: &[Field], | |
2653 | cattrs: &attr::Container, | |
2654 | ) -> (Fragment, Fragment, Fragment) { | |
0531ce1d XL |
2655 | assert!(!cattrs.has_flatten()); |
2656 | ||
ff7c6d11 XL |
2657 | let field_names_idents: Vec<_> = fields |
2658 | .iter() | |
2659 | .enumerate() | |
2660 | .filter(|&(_, field)| !field.attrs.skip_deserializing()) | |
f9f354fc XL |
2661 | .map(|(i, field)| { |
2662 | ( | |
2663 | field.attrs.name().deserialize_name(), | |
2664 | field_i(i), | |
2665 | field.attrs.aliases(), | |
2666 | ) | |
2667 | }) | |
ff7c6d11 XL |
2668 | .collect(); |
2669 | ||
2670 | let fields_stmt = { | |
f9f354fc | 2671 | let field_names = field_names_idents.iter().map(|(name, _, _)| name); |
ff7c6d11 XL |
2672 | quote_block! { |
2673 | const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; | |
2674 | } | |
2675 | }; | |
2676 | ||
0731742a | 2677 | let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); |
ff7c6d11 XL |
2678 | |
2679 | let visit_map = deserialize_map_in_place(params, fields, cattrs); | |
2680 | ||
2681 | (field_visitor, fields_stmt, visit_map) | |
2682 | } | |
2683 | ||
2684 | #[cfg(feature = "deserialize_in_place")] | |
2685 | fn deserialize_map_in_place( | |
2686 | params: &Parameters, | |
2687 | fields: &[Field], | |
2688 | cattrs: &attr::Container, | |
2689 | ) -> Fragment { | |
0531ce1d XL |
2690 | assert!(!cattrs.has_flatten()); |
2691 | ||
ff7c6d11 XL |
2692 | // Create the field names for the fields. |
2693 | let fields_names: Vec<_> = fields | |
2694 | .iter() | |
2695 | .enumerate() | |
2696 | .map(|(i, field)| (field, field_i(i))) | |
2697 | .collect(); | |
2698 | ||
b7449926 XL |
2699 | // For deserialize_in_place, declare booleans for each field that will be |
2700 | // deserialized. | |
ff7c6d11 XL |
2701 | let let_flags = fields_names |
2702 | .iter() | |
2703 | .filter(|&&(field, _)| !field.attrs.skip_deserializing()) | |
f9f354fc | 2704 | .map(|(_, name)| { |
ff7c6d11 XL |
2705 | quote! { |
2706 | let mut #name: bool = false; | |
2707 | } | |
2708 | }); | |
2709 | ||
2710 | // Match arms to extract a value for a field. | |
2711 | let value_arms_from = fields_names | |
2712 | .iter() | |
2713 | .filter(|&&(field, _)| !field.attrs.skip_deserializing()) | |
f9f354fc | 2714 | .map(|(field, name)| { |
ff7c6d11 | 2715 | let deser_name = field.attrs.name().deserialize_name(); |
8faf50e0 | 2716 | let member = &field.member; |
ff7c6d11 XL |
2717 | |
2718 | let visit = match field.attrs.deserialize_with() { | |
2719 | None => { | |
2720 | quote! { | |
5869c6ff | 2721 | try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::InPlaceSeed(&mut self.place.#member))) |
ff7c6d11 XL |
2722 | } |
2723 | } | |
2724 | Some(path) => { | |
2725 | let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); | |
2726 | quote!({ | |
2727 | #wrapper | |
f9f354fc | 2728 | self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { |
5869c6ff XL |
2729 | _serde::__private::Ok(__wrapper) => __wrapper.value, |
2730 | _serde::__private::Err(__err) => { | |
2731 | return _serde::__private::Err(__err); | |
f9f354fc XL |
2732 | } |
2733 | }; | |
ff7c6d11 XL |
2734 | }) |
2735 | } | |
2736 | }; | |
2737 | quote! { | |
2738 | __Field::#name => { | |
2739 | if #name { | |
5869c6ff | 2740 | return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); |
ff7c6d11 XL |
2741 | } |
2742 | #visit; | |
2743 | #name = true; | |
2744 | } | |
2745 | } | |
2746 | }); | |
2747 | ||
2748 | // Visit ignored values to consume them | |
2749 | let ignored_arm = if cattrs.deny_unknown_fields() { | |
2750 | None | |
2751 | } else { | |
2752 | Some(quote! { | |
2753 | _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } | |
2754 | }) | |
2755 | }; | |
2756 | ||
2757 | let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); | |
2758 | ||
2759 | let match_keys = if cattrs.deny_unknown_fields() && all_skipped { | |
2760 | quote! { | |
2761 | // FIXME: Once we drop support for Rust 1.15: | |
5869c6ff XL |
2762 | // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); |
2763 | _serde::__private::Option::map( | |
ff7c6d11 XL |
2764 | try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), |
2765 | |__impossible| match __impossible {}); | |
2766 | } | |
2767 | } else { | |
2768 | quote! { | |
5869c6ff | 2769 | while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { |
ff7c6d11 XL |
2770 | match __key { |
2771 | #(#value_arms_from)* | |
2772 | #ignored_arm | |
2773 | } | |
2774 | } | |
2775 | } | |
2776 | }; | |
2777 | ||
2778 | let check_flags = fields_names | |
2779 | .iter() | |
2780 | .filter(|&&(field, _)| !field.attrs.skip_deserializing()) | |
f9f354fc | 2781 | .map(|(field, name)| { |
0531ce1d | 2782 | let missing_expr = expr_is_missing(field, cattrs); |
ff7c6d11 | 2783 | // If missing_expr unconditionally returns an error, don't try |
8faf50e0 XL |
2784 | // to assign its value to self.place. |
2785 | if field.attrs.default().is_none() | |
2786 | && cattrs.default().is_none() | |
2787 | && field.attrs.deserialize_with().is_some() | |
83c7162d | 2788 | { |
ff7c6d11 XL |
2789 | let missing_expr = Stmts(missing_expr); |
2790 | quote! { | |
2791 | if !#name { | |
2792 | #missing_expr; | |
2793 | } | |
2794 | } | |
2795 | } else { | |
8faf50e0 | 2796 | let member = &field.member; |
ff7c6d11 XL |
2797 | let missing_expr = Expr(missing_expr); |
2798 | quote! { | |
2799 | if !#name { | |
8faf50e0 | 2800 | self.place.#member = #missing_expr; |
ff7c6d11 XL |
2801 | }; |
2802 | } | |
2803 | } | |
2804 | }); | |
2805 | ||
2806 | let this = ¶ms.this; | |
2807 | let (_, _, ty_generics, _) = split_with_de_lifetime(params); | |
2808 | ||
f9f354fc | 2809 | let let_default = match cattrs.default() { |
ff7c6d11 | 2810 | attr::Default::Default => Some(quote!( |
5869c6ff | 2811 | let __default: #this #ty_generics = _serde::__private::Default::default(); |
ff7c6d11 | 2812 | )), |
f9f354fc | 2813 | attr::Default::Path(path) => Some(quote!( |
ff7c6d11 XL |
2814 | let __default: #this #ty_generics = #path(); |
2815 | )), | |
2816 | attr::Default::None => { | |
2817 | // We don't need the default value, to prevent an unused variable warning | |
2818 | // we'll leave the line empty. | |
2819 | None | |
2820 | } | |
2821 | }; | |
2822 | ||
2823 | quote_block! { | |
2824 | #(#let_flags)* | |
2825 | ||
2826 | #match_keys | |
2827 | ||
2828 | #let_default | |
2829 | ||
2830 | #(#check_flags)* | |
2831 | ||
5869c6ff | 2832 | _serde::__private::Ok(()) |
ff7c6d11 XL |
2833 | } |
2834 | } | |
2835 | ||
3b2f2976 | 2836 | fn field_i(i: usize) -> Ident { |
83c7162d | 2837 | Ident::new(&format!("__field{}", i), Span::call_site()) |
3b2f2976 XL |
2838 | } |
2839 | ||
2840 | /// This function wraps the expression in `#[serde(deserialize_with = "...")]` | |
2841 | /// in a trait to prevent it from accessing the internal `Deserialize` state. | |
2842 | fn wrap_deserialize_with( | |
2843 | params: &Parameters, | |
8faf50e0 | 2844 | value_ty: &TokenStream, |
0531ce1d | 2845 | deserialize_with: &syn::ExprPath, |
8faf50e0 | 2846 | ) -> (TokenStream, TokenStream) { |
3b2f2976 | 2847 | let this = ¶ms.this; |
ff7c6d11 XL |
2848 | let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = |
2849 | split_with_de_lifetime(params); | |
ea8adc8c | 2850 | let delife = params.borrowed.de_lifetime(); |
3b2f2976 XL |
2851 | |
2852 | let wrapper = quote! { | |
2853 | struct __DeserializeWith #de_impl_generics #where_clause { | |
ea8adc8c | 2854 | value: #value_ty, |
5869c6ff XL |
2855 | phantom: _serde::__private::PhantomData<#this #ty_generics>, |
2856 | lifetime: _serde::__private::PhantomData<&#delife ()>, | |
3b2f2976 XL |
2857 | } |
2858 | ||
ea8adc8c | 2859 | impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { |
5869c6ff | 2860 | fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error> |
8faf50e0 XL |
2861 | where |
2862 | __D: _serde::Deserializer<#delife>, | |
3b2f2976 | 2863 | { |
5869c6ff | 2864 | _serde::__private::Ok(__DeserializeWith { |
3b2f2976 | 2865 | value: try!(#deserialize_with(__deserializer)), |
5869c6ff XL |
2866 | phantom: _serde::__private::PhantomData, |
2867 | lifetime: _serde::__private::PhantomData, | |
3b2f2976 XL |
2868 | }) |
2869 | } | |
2870 | } | |
2871 | }; | |
2872 | ||
2873 | let wrapper_ty = quote!(__DeserializeWith #de_ty_generics); | |
2874 | ||
2875 | (wrapper, wrapper_ty) | |
2876 | } | |
2877 | ||
ea8adc8c XL |
2878 | fn wrap_deserialize_field_with( |
2879 | params: &Parameters, | |
0531ce1d XL |
2880 | field_ty: &syn::Type, |
2881 | deserialize_with: &syn::ExprPath, | |
8faf50e0 | 2882 | ) -> (TokenStream, TokenStream) { |
0531ce1d | 2883 | wrap_deserialize_with(params, "e!(#field_ty), deserialize_with) |
ea8adc8c XL |
2884 | } |
2885 | ||
2886 | fn wrap_deserialize_variant_with( | |
2887 | params: &Parameters, | |
2888 | variant: &Variant, | |
0531ce1d | 2889 | deserialize_with: &syn::ExprPath, |
8faf50e0 | 2890 | ) -> (TokenStream, TokenStream, TokenStream) { |
ea8adc8c XL |
2891 | let field_tys = variant.fields.iter().map(|field| field.ty); |
2892 | let (wrapper, wrapper_ty) = | |
0531ce1d | 2893 | wrap_deserialize_with(params, "e!((#(#field_tys),*)), deserialize_with); |
ea8adc8c | 2894 | |
c295e0f8 XL |
2895 | let unwrap_fn = unwrap_to_variant_closure(params, variant, true); |
2896 | ||
2897 | (wrapper, wrapper_ty, unwrap_fn) | |
2898 | } | |
2899 | ||
2900 | // Generates closure that converts single input parameter to the final value. | |
2901 | fn unwrap_to_variant_closure( | |
2902 | params: &Parameters, | |
2903 | variant: &Variant, | |
2904 | with_wrapper: bool, | |
2905 | ) -> TokenStream { | |
2906 | let this = ¶ms.this; | |
2907 | let variant_ident = &variant.ident; | |
2908 | ||
2909 | let (arg, wrapper) = if with_wrapper { | |
2910 | (quote! { __wrap }, quote! { __wrap.value }) | |
2911 | } else { | |
2912 | let field_tys = variant.fields.iter().map(|field| field.ty); | |
2913 | (quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap }) | |
2914 | }; | |
2915 | ||
83c7162d XL |
2916 | let field_access = (0..variant.fields.len()).map(|n| { |
2917 | Member::Unnamed(Index { | |
2918 | index: n as u32, | |
2919 | span: Span::call_site(), | |
2920 | }) | |
2921 | }); | |
c295e0f8 XL |
2922 | |
2923 | match variant.style { | |
83c7162d | 2924 | Style::Struct if variant.fields.len() == 1 => { |
8faf50e0 | 2925 | let member = &variant.fields[0].member; |
83c7162d | 2926 | quote! { |
c295e0f8 | 2927 | |#arg| #this::#variant_ident { #member: #wrapper } |
83c7162d XL |
2928 | } |
2929 | } | |
ea8adc8c | 2930 | Style::Struct => { |
8faf50e0 | 2931 | let members = variant.fields.iter().map(|field| &field.member); |
83c7162d | 2932 | quote! { |
c295e0f8 | 2933 | |#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* } |
ea8adc8c | 2934 | } |
83c7162d XL |
2935 | } |
2936 | Style::Tuple => quote! { | |
c295e0f8 | 2937 | |#arg| #this::#variant_ident(#(#wrapper.#field_access),*) |
83c7162d XL |
2938 | }, |
2939 | Style::Newtype => quote! { | |
c295e0f8 | 2940 | |#arg| #this::#variant_ident(#wrapper) |
83c7162d XL |
2941 | }, |
2942 | Style::Unit => quote! { | |
c295e0f8 | 2943 | |#arg| #this::#variant_ident |
83c7162d | 2944 | }, |
c295e0f8 | 2945 | } |
ea8adc8c XL |
2946 | } |
2947 | ||
3b2f2976 | 2948 | fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { |
f9f354fc | 2949 | match field.attrs.default() { |
3b2f2976 | 2950 | attr::Default::Default => { |
0731742a | 2951 | let span = field.original.span(); |
5869c6ff | 2952 | let func = quote_spanned!(span=> _serde::__private::Default::default); |
0731742a | 2953 | return quote_expr!(#func()); |
3b2f2976 | 2954 | } |
f9f354fc | 2955 | attr::Default::Path(path) => { |
3b2f2976 XL |
2956 | return quote_expr!(#path()); |
2957 | } | |
2958 | attr::Default::None => { /* below */ } | |
2959 | } | |
2960 | ||
2961 | match *cattrs.default() { | |
ff7c6d11 | 2962 | attr::Default::Default | attr::Default::Path(_) => { |
8faf50e0 XL |
2963 | let member = &field.member; |
2964 | return quote_expr!(__default.#member); | |
3b2f2976 XL |
2965 | } |
2966 | attr::Default::None => { /* below */ } | |
2967 | } | |
2968 | ||
2969 | let name = field.attrs.name().deserialize_name(); | |
2970 | match field.attrs.deserialize_with() { | |
2971 | None => { | |
83c7162d | 2972 | let span = field.original.span(); |
5869c6ff | 2973 | let func = quote_spanned!(span=> _serde::__private::de::missing_field); |
3b2f2976 | 2974 | quote_expr! { |
0531ce1d | 2975 | try!(#func(#name)) |
3b2f2976 XL |
2976 | } |
2977 | } | |
2978 | Some(_) => { | |
2979 | quote_expr! { | |
5869c6ff | 2980 | return _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#name)) |
3b2f2976 XL |
2981 | } |
2982 | } | |
2983 | } | |
2984 | } | |
2985 | ||
f9f354fc XL |
2986 | fn effective_style(variant: &Variant) -> Style { |
2987 | match variant.style { | |
2988 | Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit, | |
2989 | other => other, | |
2990 | } | |
2991 | } | |
2992 | ||
3b2f2976 | 2993 | struct DeImplGenerics<'a>(&'a Parameters); |
ff7c6d11 XL |
2994 | #[cfg(feature = "deserialize_in_place")] |
2995 | struct InPlaceImplGenerics<'a>(&'a Parameters); | |
3b2f2976 XL |
2996 | |
2997 | impl<'a> ToTokens for DeImplGenerics<'a> { | |
8faf50e0 | 2998 | fn to_tokens(&self, tokens: &mut TokenStream) { |
3b2f2976 | 2999 | let mut generics = self.0.generics.clone(); |
ea8adc8c | 3000 | if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() { |
0531ce1d XL |
3001 | generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) |
3002 | .into_iter() | |
3003 | .chain(generics.params) | |
3004 | .collect(); | |
ea8adc8c | 3005 | } |
3b2f2976 XL |
3006 | let (impl_generics, _, _) = generics.split_for_impl(); |
3007 | impl_generics.to_tokens(tokens); | |
3008 | } | |
3009 | } | |
3010 | ||
ff7c6d11 XL |
3011 | #[cfg(feature = "deserialize_in_place")] |
3012 | impl<'a> ToTokens for InPlaceImplGenerics<'a> { | |
8faf50e0 | 3013 | fn to_tokens(&self, tokens: &mut TokenStream) { |
ff7c6d11 XL |
3014 | let place_lifetime = place_lifetime(); |
3015 | let mut generics = self.0.generics.clone(); | |
3016 | ||
3017 | // Add lifetime for `&'place mut Self, and `'a: 'place` | |
0531ce1d | 3018 | for param in &mut generics.params { |
f9f354fc XL |
3019 | match param { |
3020 | syn::GenericParam::Lifetime(param) => { | |
8faf50e0 | 3021 | param.bounds.push(place_lifetime.lifetime.clone()); |
0531ce1d | 3022 | } |
f9f354fc | 3023 | syn::GenericParam::Type(param) => { |
8faf50e0 XL |
3024 | param.bounds.push(syn::TypeParamBound::Lifetime( |
3025 | place_lifetime.lifetime.clone(), | |
3026 | )); | |
0531ce1d XL |
3027 | } |
3028 | syn::GenericParam::Const(_) => {} | |
3029 | } | |
ff7c6d11 | 3030 | } |
0531ce1d XL |
3031 | generics.params = Some(syn::GenericParam::Lifetime(place_lifetime)) |
3032 | .into_iter() | |
3033 | .chain(generics.params) | |
3034 | .collect(); | |
ff7c6d11 | 3035 | if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() { |
0531ce1d XL |
3036 | generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) |
3037 | .into_iter() | |
3038 | .chain(generics.params) | |
3039 | .collect(); | |
ff7c6d11 XL |
3040 | } |
3041 | let (impl_generics, _, _) = generics.split_for_impl(); | |
3042 | impl_generics.to_tokens(tokens); | |
3043 | } | |
3044 | } | |
3045 | ||
3046 | #[cfg(feature = "deserialize_in_place")] | |
3047 | impl<'a> DeImplGenerics<'a> { | |
3048 | fn in_place(self) -> InPlaceImplGenerics<'a> { | |
3049 | InPlaceImplGenerics(self.0) | |
3050 | } | |
3051 | } | |
3052 | ||
0531ce1d | 3053 | struct DeTypeGenerics<'a>(&'a Parameters); |
ff7c6d11 | 3054 | #[cfg(feature = "deserialize_in_place")] |
0531ce1d | 3055 | struct InPlaceTypeGenerics<'a>(&'a Parameters); |
3b2f2976 | 3056 | |
0531ce1d | 3057 | impl<'a> ToTokens for DeTypeGenerics<'a> { |
8faf50e0 | 3058 | fn to_tokens(&self, tokens: &mut TokenStream) { |
ea8adc8c XL |
3059 | let mut generics = self.0.generics.clone(); |
3060 | if self.0.borrowed.de_lifetime_def().is_some() { | |
0531ce1d XL |
3061 | let def = syn::LifetimeDef { |
3062 | attrs: Vec::new(), | |
83c7162d | 3063 | lifetime: syn::Lifetime::new("'de", Span::call_site()), |
0531ce1d XL |
3064 | colon_token: None, |
3065 | bounds: Punctuated::new(), | |
3066 | }; | |
3067 | generics.params = Some(syn::GenericParam::Lifetime(def)) | |
3068 | .into_iter() | |
3069 | .chain(generics.params) | |
3070 | .collect(); | |
ea8adc8c | 3071 | } |
3b2f2976 XL |
3072 | let (_, ty_generics, _) = generics.split_for_impl(); |
3073 | ty_generics.to_tokens(tokens); | |
3074 | } | |
3075 | } | |
3076 | ||
ff7c6d11 | 3077 | #[cfg(feature = "deserialize_in_place")] |
0531ce1d | 3078 | impl<'a> ToTokens for InPlaceTypeGenerics<'a> { |
8faf50e0 | 3079 | fn to_tokens(&self, tokens: &mut TokenStream) { |
ff7c6d11 | 3080 | let mut generics = self.0.generics.clone(); |
0531ce1d XL |
3081 | generics.params = Some(syn::GenericParam::Lifetime(place_lifetime())) |
3082 | .into_iter() | |
3083 | .chain(generics.params) | |
3084 | .collect(); | |
ff7c6d11 XL |
3085 | |
3086 | if self.0.borrowed.de_lifetime_def().is_some() { | |
0531ce1d XL |
3087 | let def = syn::LifetimeDef { |
3088 | attrs: Vec::new(), | |
83c7162d | 3089 | lifetime: syn::Lifetime::new("'de", Span::call_site()), |
0531ce1d XL |
3090 | colon_token: None, |
3091 | bounds: Punctuated::new(), | |
3092 | }; | |
3093 | generics.params = Some(syn::GenericParam::Lifetime(def)) | |
3094 | .into_iter() | |
3095 | .chain(generics.params) | |
3096 | .collect(); | |
ff7c6d11 XL |
3097 | } |
3098 | let (_, ty_generics, _) = generics.split_for_impl(); | |
3099 | ty_generics.to_tokens(tokens); | |
3100 | } | |
3101 | } | |
3102 | ||
3103 | #[cfg(feature = "deserialize_in_place")] | |
0531ce1d XL |
3104 | impl<'a> DeTypeGenerics<'a> { |
3105 | fn in_place(self) -> InPlaceTypeGenerics<'a> { | |
3106 | InPlaceTypeGenerics(self.0) | |
ff7c6d11 XL |
3107 | } |
3108 | } | |
3109 | ||
3110 | #[cfg(feature = "deserialize_in_place")] | |
3111 | fn place_lifetime() -> syn::LifetimeDef { | |
0531ce1d XL |
3112 | syn::LifetimeDef { |
3113 | attrs: Vec::new(), | |
83c7162d | 3114 | lifetime: syn::Lifetime::new("'place", Span::call_site()), |
0531ce1d XL |
3115 | colon_token: None, |
3116 | bounds: Punctuated::new(), | |
3117 | } | |
ff7c6d11 XL |
3118 | } |
3119 | ||
3120 | fn split_with_de_lifetime( | |
3121 | params: &Parameters, | |
3122 | ) -> ( | |
3123 | DeImplGenerics, | |
0531ce1d XL |
3124 | DeTypeGenerics, |
3125 | syn::TypeGenerics, | |
3126 | Option<&syn::WhereClause>, | |
ff7c6d11 | 3127 | ) { |
0531ce1d XL |
3128 | let de_impl_generics = DeImplGenerics(params); |
3129 | let de_ty_generics = DeTypeGenerics(params); | |
3b2f2976 XL |
3130 | let (_, ty_generics, where_clause) = params.generics.split_for_impl(); |
3131 | (de_impl_generics, de_ty_generics, ty_generics, where_clause) | |
3132 | } |