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