1use crate::de::{FieldWithAliases, Parameters};
5use crate::fragment::{Fragment, Stmts};
6use crate::internals::ast::{Style, Variant};
7use crate::internals::attr;
8use crate::private;
9use proc_macro2::{Literal, TokenStream};
10use quote::{quote, ToTokens};
11
12pub(super) fn deserialize_custom(
15 params: &Parameters,
16 variants: &[Variant],
17 cattrs: &attr::Container,
18) -> Fragment {
19 let is_variant = match cattrs.identifier() {
20 attr::Identifier::Variant => true,
21 attr::Identifier::Field => false,
22 attr::Identifier::No => unreachable!(),
23 };
24
25 let this_type = params.this_type.to_token_stream();
26 let this_value = params.this_value.to_token_stream();
27
28 let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
29 let last_ident = &last.ident;
30 if last.attrs.other() {
31 let ordinary = &variants[..variants.len() - 1];
35 let fallthrough = quote!(_serde::#private::Ok(#this_value::#last_ident));
36 (ordinary, Some(fallthrough), None)
37 } else if let Style::Newtype = last.style {
38 let ordinary = &variants[..variants.len() - 1];
39 let fallthrough = |value| {
40 quote! {
41 _serde::#private::Result::map(
42 _serde::Deserialize::deserialize(
43 _serde::#private::de::IdentifierDeserializer::from(#value)
44 ),
45 #this_value::#last_ident)
46 }
47 };
48 (
49 ordinary,
50 Some(fallthrough(quote!(__value))),
51 Some(fallthrough(quote!(_serde::#private::de::Borrowed(
52 __value
53 )))),
54 )
55 } else {
56 (variants, None, None)
57 }
58 } else {
59 (variants, None, None)
60 };
61
62 let idents_aliases: Vec<_> = ordinary
63 .iter()
64 .map(|variant| FieldWithAliases {
65 ident: variant.ident.clone(),
66 aliases: variant.attrs.aliases(),
67 })
68 .collect();
69
70 let names = idents_aliases.iter().flat_map(|variant| variant.aliases);
71
72 let names_const = if fallthrough.is_some() {
73 None
74 } else if is_variant {
75 let variants = quote! {
76 #[doc(hidden)]
77 const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
78 };
79 Some(variants)
80 } else {
81 let fields = quote! {
82 #[doc(hidden)]
83 const FIELDS: &'static [&'static str] = &[ #(#names),* ];
84 };
85 Some(fields)
86 };
87
88 let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
89 params.generics_with_de_lifetime();
90 let delife = params.borrowed.de_lifetime();
91 let visitor_impl = Stmts(deserialize_identifier(
92 &this_value,
93 &idents_aliases,
94 is_variant,
95 fallthrough,
96 fallthrough_borrowed,
97 false,
98 cattrs.expecting(),
99 ));
100
101 quote_block! {
102 #names_const
103
104 #[doc(hidden)]
105 struct __FieldVisitor #de_impl_generics #where_clause {
106 marker: _serde::#private::PhantomData<#this_type #ty_generics>,
107 lifetime: _serde::#private::PhantomData<&#delife ()>,
108 }
109
110 #[automatically_derived]
111 impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
112 type Value = #this_type #ty_generics;
113
114 #visitor_impl
115 }
116
117 let __visitor = __FieldVisitor {
118 marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
119 lifetime: _serde::#private::PhantomData,
120 };
121 _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
122 }
123}
124
125pub(super) fn deserialize_generated(
126 deserialized_fields: &[FieldWithAliases],
127 has_flatten: bool,
128 is_variant: bool,
129 ignore_variant: Option<TokenStream>,
130 fallthrough: Option<TokenStream>,
131) -> Fragment {
132 let this_value = quote!(__Field);
133 let field_idents: &Vec<_> = &deserialized_fields
134 .iter()
135 .map(|field| &field.ident)
136 .collect();
137
138 let visitor_impl = Stmts(deserialize_identifier(
139 &this_value,
140 deserialized_fields,
141 is_variant,
142 fallthrough,
143 None,
144 !is_variant && has_flatten,
145 None,
146 ));
147
148 let lifetime = if !is_variant && has_flatten {
149 Some(quote!(<'de>))
150 } else {
151 None
152 };
153
154 quote_block! {
155 #[allow(non_camel_case_types)]
156 #[doc(hidden)]
157 enum __Field #lifetime {
158 #(#field_idents,)*
159 #ignore_variant
160 }
161
162 #[doc(hidden)]
163 struct __FieldVisitor;
164
165 #[automatically_derived]
166 impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
167 type Value = __Field #lifetime;
168
169 #visitor_impl
170 }
171
172 #[automatically_derived]
173 impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
174 #[inline]
175 fn deserialize<__D>(__deserializer: __D) -> _serde::#private::Result<Self, __D::Error>
176 where
177 __D: _serde::Deserializer<'de>,
178 {
179 _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
180 }
181 }
182 }
183}
184
185fn deserialize_identifier(
186 this_value: &TokenStream,
187 deserialized_fields: &[FieldWithAliases],
188 is_variant: bool,
189 fallthrough: Option<TokenStream>,
190 fallthrough_borrowed: Option<TokenStream>,
191 collect_other_fields: bool,
192 expecting: Option<&str>,
193) -> Fragment {
194 let str_mapping = deserialized_fields.iter().map(|field| {
195 let ident = &field.ident;
196 let aliases = field.aliases;
197 let private2 = private;
198 quote! {
200 #(
201 #aliases => _serde::#private2::Ok(#this_value::#ident),
202 )*
203 }
204 });
205 let bytes_mapping = deserialized_fields.iter().map(|field| {
206 let ident = &field.ident;
207 let aliases = field
209 .aliases
210 .iter()
211 .map(|alias| Literal::byte_string(alias.value.as_bytes()));
212 let private2 = private;
213 quote! {
214 #(
215 #aliases => _serde::#private2::Ok(#this_value::#ident),
216 )*
217 }
218 });
219
220 let expecting = expecting.unwrap_or(if is_variant {
221 "variant identifier"
222 } else {
223 "field identifier"
224 });
225
226 let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
227 None
228 } else {
229 Some(quote! {
230 let __value = &_serde::#private::from_utf8_lossy(__value);
231 })
232 };
233
234 let (
235 value_as_str_content,
236 value_as_borrowed_str_content,
237 value_as_bytes_content,
238 value_as_borrowed_bytes_content,
239 ) = if collect_other_fields {
240 (
241 Some(quote! {
242 let __value = _serde::#private::de::Content::String(_serde::#private::ToString::to_string(__value));
243 }),
244 Some(quote! {
245 let __value = _serde::#private::de::Content::Str(__value);
246 }),
247 Some(quote! {
248 let __value = _serde::#private::de::Content::ByteBuf(__value.to_vec());
249 }),
250 Some(quote! {
251 let __value = _serde::#private::de::Content::Bytes(__value);
252 }),
253 )
254 } else {
255 (None, None, None, None)
256 };
257
258 let fallthrough_arm_tokens;
259 let fallthrough_arm = if let Some(fallthrough) = &fallthrough {
260 fallthrough
261 } else if is_variant {
262 fallthrough_arm_tokens = quote! {
263 _serde::#private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
264 };
265 &fallthrough_arm_tokens
266 } else {
267 fallthrough_arm_tokens = quote! {
268 _serde::#private::Err(_serde::de::Error::unknown_field(__value, FIELDS))
269 };
270 &fallthrough_arm_tokens
271 };
272
273 let visit_other = if collect_other_fields {
274 quote! {
275 fn visit_bool<__E>(self, __value: bool) -> _serde::#private::Result<Self::Value, __E>
276 where
277 __E: _serde::de::Error,
278 {
279 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Bool(__value)))
280 }
281
282 fn visit_i8<__E>(self, __value: i8) -> _serde::#private::Result<Self::Value, __E>
283 where
284 __E: _serde::de::Error,
285 {
286 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I8(__value)))
287 }
288
289 fn visit_i16<__E>(self, __value: i16) -> _serde::#private::Result<Self::Value, __E>
290 where
291 __E: _serde::de::Error,
292 {
293 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I16(__value)))
294 }
295
296 fn visit_i32<__E>(self, __value: i32) -> _serde::#private::Result<Self::Value, __E>
297 where
298 __E: _serde::de::Error,
299 {
300 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I32(__value)))
301 }
302
303 fn visit_i64<__E>(self, __value: i64) -> _serde::#private::Result<Self::Value, __E>
304 where
305 __E: _serde::de::Error,
306 {
307 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I64(__value)))
308 }
309
310 fn visit_u8<__E>(self, __value: u8) -> _serde::#private::Result<Self::Value, __E>
311 where
312 __E: _serde::de::Error,
313 {
314 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U8(__value)))
315 }
316
317 fn visit_u16<__E>(self, __value: u16) -> _serde::#private::Result<Self::Value, __E>
318 where
319 __E: _serde::de::Error,
320 {
321 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U16(__value)))
322 }
323
324 fn visit_u32<__E>(self, __value: u32) -> _serde::#private::Result<Self::Value, __E>
325 where
326 __E: _serde::de::Error,
327 {
328 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U32(__value)))
329 }
330
331 fn visit_u64<__E>(self, __value: u64) -> _serde::#private::Result<Self::Value, __E>
332 where
333 __E: _serde::de::Error,
334 {
335 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U64(__value)))
336 }
337
338 fn visit_f32<__E>(self, __value: f32) -> _serde::#private::Result<Self::Value, __E>
339 where
340 __E: _serde::de::Error,
341 {
342 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::F32(__value)))
343 }
344
345 fn visit_f64<__E>(self, __value: f64) -> _serde::#private::Result<Self::Value, __E>
346 where
347 __E: _serde::de::Error,
348 {
349 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::F64(__value)))
350 }
351
352 fn visit_char<__E>(self, __value: char) -> _serde::#private::Result<Self::Value, __E>
353 where
354 __E: _serde::de::Error,
355 {
356 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Char(__value)))
357 }
358
359 fn visit_unit<__E>(self) -> _serde::#private::Result<Self::Value, __E>
360 where
361 __E: _serde::de::Error,
362 {
363 _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Unit))
364 }
365 }
366 } else {
367 let u64_mapping = deserialized_fields.iter().enumerate().map(|(i, field)| {
368 let i = i as u64;
369 let ident = &field.ident;
370 quote!(#i => _serde::#private::Ok(#this_value::#ident))
371 });
372
373 let u64_fallthrough_arm_tokens;
374 let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
375 fallthrough
376 } else {
377 let index_expecting = if is_variant { "variant" } else { "field" };
378 let fallthrough_msg = format!(
379 "{} index 0 <= i < {}",
380 index_expecting,
381 deserialized_fields.len(),
382 );
383 u64_fallthrough_arm_tokens = quote! {
384 _serde::#private::Err(_serde::de::Error::invalid_value(
385 _serde::de::Unexpected::Unsigned(__value),
386 &#fallthrough_msg,
387 ))
388 };
389 &u64_fallthrough_arm_tokens
390 };
391
392 quote! {
393 fn visit_u64<__E>(self, __value: u64) -> _serde::#private::Result<Self::Value, __E>
394 where
395 __E: _serde::de::Error,
396 {
397 match __value {
398 #(#u64_mapping,)*
399 _ => #u64_fallthrough_arm,
400 }
401 }
402 }
403 };
404
405 let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
406 let str_mapping = str_mapping.clone();
407 let bytes_mapping = bytes_mapping.clone();
408 let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
409 Some(quote! {
410 fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::#private::Result<Self::Value, __E>
411 where
412 __E: _serde::de::Error,
413 {
414 match __value {
415 #(#str_mapping)*
416 _ => {
417 #value_as_borrowed_str_content
418 #fallthrough_borrowed_arm
419 }
420 }
421 }
422
423 fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::#private::Result<Self::Value, __E>
424 where
425 __E: _serde::de::Error,
426 {
427 match __value {
428 #(#bytes_mapping)*
429 _ => {
430 #bytes_to_str
431 #value_as_borrowed_bytes_content
432 #fallthrough_borrowed_arm
433 }
434 }
435 }
436 })
437 } else {
438 None
439 };
440
441 quote_block! {
442 fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
443 _serde::#private::Formatter::write_str(__formatter, #expecting)
444 }
445
446 #visit_other
447
448 fn visit_str<__E>(self, __value: &str) -> _serde::#private::Result<Self::Value, __E>
449 where
450 __E: _serde::de::Error,
451 {
452 match __value {
453 #(#str_mapping)*
454 _ => {
455 #value_as_str_content
456 #fallthrough_arm
457 }
458 }
459 }
460
461 fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::#private::Result<Self::Value, __E>
462 where
463 __E: _serde::de::Error,
464 {
465 match __value {
466 #(#bytes_mapping)*
467 _ => {
468 #bytes_to_str
469 #value_as_bytes_content
470 #fallthrough_arm
471 }
472 }
473 }
474
475 #visit_borrowed
476 }
477}