educe/trait_handlers/hash/
hash_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 HashUnionHandler;
8
9impl TraitHandler for HashUnionHandler {
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_hash_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::hash::Hash for #ident #ty_generics #where_clause {
42 #[inline]
43 fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
44 let size = ::core::mem::size_of::<Self>();
45 let data = unsafe { ::core::slice::from_raw_parts(self as *const Self as *const u8, size) };
46
47 ::core::hash::Hash::hash(data, state)
48 }
49 }
50 });
51
52 Ok(())
53 }
54}