1use emit::{collect_missing_errors, initialize_from_shadow, ImplDeserGenerics};
8use indexmap::IndexSet;
9use proc_macro::TokenStream;
10use quote::{format_ident, quote};
11use syn::{parse_macro_input, DeriveInput};
12use unsupported::reject_unsupported_inputs;
13
14mod attr;
15mod emit;
16mod filter_attributes;
17mod model;
18mod unsupported;
19
20#[proc_macro_derive(Deserialize, attributes(serde, bronzerde))]
21pub fn derive_deserialize(input: TokenStream) -> TokenStream {
22 let input = parse_macro_input!(input as DeriveInput);
23
24 if let Err(e) = reject_unsupported_inputs(&input) {
25 return e.into_compile_error().into();
26 }
27
28 let name = &input.ident;
29 let shadow_type = model::ShadowType::new(format_ident!("__ImplDeserializeFor{}", name), &input);
30 let shadow_type_ident = &shadow_type.0.ident;
31
32 let shadow_binding = format_ident!("__shadowed");
33 let initialize_from_shadow = initialize_from_shadow(
34 &input.data,
35 &format_ident!("Self"),
36 &shadow_binding,
37 shadow_type_ident,
38 );
39
40 let companion_type =
41 model::PermissiveCompanionType::new(format_ident!("__ImplEDeserializeFor{}", name), &input);
42 let companion_type_ident = &companion_type.ty_.ident;
43 let companion_binding = format_ident!("__companion");
44 let deserializer_generic_ident = format_ident!("__D");
45 let n_errors = format_ident!("__n_errors");
46 let collect_missing_errors = collect_missing_errors(
47 &input.data,
48 companion_type_ident,
49 &companion_binding,
50 &n_errors,
51 );
52
53 let deser_generics = ImplDeserGenerics::new(&input, &IndexSet::new());
54 let (impl_generics, ty_generics, where_clause) = deser_generics.split_for_impl();
55
56 let human_deser_generics =
57 ImplDeserGenerics::new(&input, &companion_type.bronzerde_aware_generics);
58 let (human_impl_generics, human_ty_generics, human_where_clause) =
59 human_deser_generics.split_for_impl();
60
61 let expanded = quote! {
62 const _: () = {
63 #companion_type
64
65 #shadow_type
66
67 #[automatically_derived]
68 impl #human_impl_generics ::bronzerde::EDeserialize<'de> for #name #human_ty_generics
69 #human_where_clause
70 {
71 fn deserialize_for_errors<#deserializer_generic_ident>(__deserializer: #deserializer_generic_ident) -> std::result::Result<(), ()>
72 where
73 #deserializer_generic_ident: ::bronzerde::_serde::Deserializer<'de>,
74 {
75 let #n_errors = ::bronzerde::reporter::ErrorReporter::n_errors();
76 let #companion_binding = <#companion_type_ident #ty_generics as ::bronzerde::_serde::Deserialize>::deserialize(__deserializer)
77 .map_err(::bronzerde::reporter::ErrorReporter::report)?;
78 #collect_missing_errors
79 }
80 }
81
82 #[automatically_derived]
83 impl #impl_generics ::bronzerde::_serde::Deserialize<'de> for #name #ty_generics
84 #where_clause
85 {
86 fn deserialize<#deserializer_generic_ident>(__deserializer: #deserializer_generic_ident) -> std::result::Result<Self, #deserializer_generic_ident::Error>
87 where
88 #deserializer_generic_ident: ::bronzerde::_serde::Deserializer<'de>,
89 {
90 let #shadow_binding = #shadow_type_ident::deserialize(__deserializer)?;
91 Ok(#initialize_from_shadow)
92 }
93 }
94 };
95 };
96
97 TokenStream::from(expanded)
98}