educe/trait_handlers/clone/
clone_union.rs

1use quote::quote;
2use syn::{Data, DeriveInput, Meta};
3
4use super::{
5    models::{FieldAttributeBuilder, TypeAttributeBuilder},
6    TraitHandler,
7};
8use crate::supported_traits::Trait;
9
10pub(crate) struct CloneUnionHandler;
11
12impl TraitHandler for CloneUnionHandler {
13    fn trait_meta_handler(
14        ast: &DeriveInput,
15        token_stream: &mut proc_macro2::TokenStream,
16        traits: &[Trait],
17        meta: &Meta,
18    ) -> syn::Result<()> {
19        let type_attribute = TypeAttributeBuilder {
20            enable_flag: true, enable_bound: true
21        }
22        .build_from_clone_meta(meta)?;
23
24        let mut field_types = vec![];
25
26        if let Data::Union(data) = &ast.data {
27            for field in data.fields.named.iter() {
28                field_types.push(&field.ty);
29                let _ = FieldAttributeBuilder {
30                    enable_method: false
31                }
32                .build_from_attributes(&field.attrs, traits)?;
33            }
34        }
35
36        let ident = &ast.ident;
37
38        let bound = type_attribute.bound.into_where_predicates_by_generic_parameters_check_types(
39            &ast.generics.params,
40            &syn::parse2(quote!(::core::marker::Copy)).unwrap(),
41            &field_types,
42            &[],
43        );
44
45        let mut generics = ast.generics.clone();
46        let where_clause = generics.make_where_clause();
47
48        for where_predicate in bound {
49            where_clause.predicates.push(where_predicate);
50        }
51
52        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
53
54        token_stream.extend(quote! {
55            impl #impl_generics ::core::clone::Clone for #ident #ty_generics #where_clause {
56                #[inline]
57                fn clone(&self) -> Self {
58                    *self
59                }
60            }
61        });
62
63        #[cfg(feature = "Copy")]
64        if traits.contains(&Trait::Copy) {
65            token_stream.extend(quote! {
66                impl #impl_generics ::core::marker::Copy for #ident #ty_generics #where_clause {
67                }
68            });
69        }
70
71        Ok(())
72    }
73}