educe/trait_handlers/partial_eq/
partial_eq_union.rs1use quote::quote;
2use syn::{Data, DeriveInput, Meta};
3
4use super::models::{FieldAttributeBuilder, TypeAttributeBuilder};
5use crate::{supported_traits::Trait, trait_handlers::TraitHandler};
6
7pub(crate) struct PartialEqUnionHandler;
8
9impl TraitHandler for PartialEqUnionHandler {
10 #[inline]
11 fn trait_meta_handler(
12 ast: &DeriveInput,
13 token_stream: &mut proc_macro2::TokenStream,
14 traits: &[Trait],
15 meta: &Meta,
16 ) -> syn::Result<()> {
17 let type_attribute =
18 TypeAttributeBuilder {
19 enable_flag: true, enable_unsafe: true, enable_bound: false
20 }
21 .build_from_partial_eq_meta(meta)?;
22
23 if !type_attribute.has_unsafe {
24 return Err(super::panic::union_without_unsafe(meta));
25 }
26
27 if let Data::Union(data) = &ast.data {
28 for field in data.fields.named.iter() {
29 let _ = FieldAttributeBuilder {
30 enable_ignore: false, enable_method: false
31 }
32 .build_from_attributes(&field.attrs, traits)?;
33 }
34 }
35
36 let ident = &ast.ident;
37
38 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
39
40 token_stream.extend(quote! {
41 impl #impl_generics ::core::cmp::PartialEq for #ident #ty_generics #where_clause {
42 #[inline]
43 fn eq(&self, other: &Self) -> bool {
44 let size = ::core::mem::size_of::<Self>();
45 let self_data = unsafe { ::core::slice::from_raw_parts(self as *const Self as *const u8, size) };
46 let other_data = unsafe { ::core::slice::from_raw_parts(other as *const Self as *const u8, size) };
47
48 ::core::cmp::PartialEq::eq(self_data, other_data)
49 }
50 }
51 });
52
53 #[cfg(feature = "Eq")]
54 if traits.contains(&Trait::Eq) {
55 token_stream.extend(quote! {
56 impl #impl_generics ::core::cmp::Eq for #ident #ty_generics #where_clause {
57 }
58 });
59 }
60
61 Ok(())
62 }
63}