educe/trait_handlers/clone/
clone_union.rs1use 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}