1//! [`Default`](trait@std::default::Default) implementation.
2
3use proc_macro2::TokenStream;
4use quote::quote;
5
6use crate::{Data, DeriveTrait, Item, SimpleType, SplitGenerics, TraitImpl};
7
8/// Dummy-struct implement [`Trait`](crate::Trait) for
9/// [`Default`](trait@std::default::Default).
10pub struct Default;
11
12impl TraitImpl for Default {
13 fn as_str(&self) -> &'static str {
14 "Default"
15 }
16
17 fn default_derive_trait(&self) -> DeriveTrait {
18 DeriveTrait::Default
19 }
20
21 fn build_signature(
22 &self,
23 _any_bound: bool,
24 _item: &Item,
25 _generics: &SplitGenerics<'_>,
26 _traits: &[DeriveTrait],
27 _trait_: &DeriveTrait,
28 body: &TokenStream,
29 ) -> TokenStream {
30 quote! {
31 fn default() -> Self {
32 #body
33 }
34 }
35 }
36
37 fn build_body(
38 &self,
39 _any_bound: bool,
40 _traits: &[DeriveTrait],
41 trait_: &DeriveTrait,
42 data: &Data,
43 ) -> TokenStream {
44 if data.is_default() {
45 let path = &data.path;
46
47 match data.simple_type() {
48 SimpleType::Struct(_) => {
49 let fields = data.iter_field_ident(**trait_);
50 let trait_path = trait_.path();
51
52 quote! { #path { #(#fields: #trait_path::default()),* } }
53 }
54 SimpleType::Tuple(_) => {
55 let trait_path = trait_.path();
56 let fields = data
57 .iter_fields(**trait_)
58 .map(|_| quote! { #trait_path::default() });
59
60 quote! { #path(#(#fields),*) }
61 }
62 SimpleType::Unit(_) => {
63 quote! { #path }
64 }
65 SimpleType::Union(_) => unreachable!("unexpected trait for union"),
66 }
67 }
68 // Skip `Default` implementation if variant isn't marked with a `default` attribute.
69 else {
70 TokenStream::new()
71 }
72 }
73}
74