pyo3_commonize_macro/
lib.rs1use proc_macro::TokenStream as TokenStream1;
2use proc_macro2::{Span, TokenStream};
3use proc_macro_error::abort;
4use syn::*;
5use template_quote::quote;
6
7fn get_tag(tokens: &TokenStream) -> usize {
8 use std::hash::{DefaultHasher, Hash, Hasher};
9 let mut hasher = DefaultHasher::new();
10 tokens.to_string().hash(&mut hasher);
11 hasher.finish() as usize
12}
13
14#[proc_macro_derive(Commonized)]
15pub fn derive_commonized(input: TokenStream1) -> TokenStream1 {
16 let item =
17 parse::<Item>(input.clone()).unwrap_or_else(|_| abort!(Span::call_site(), "Bad item"));
18 let (generics, ident) = match &item {
19 Item::Enum(ie) => (&ie.generics, &ie.ident),
20 Item::Struct(is) => (&is.generics, &is.ident),
21 _ => abort!(Span::call_site(), "Bad item"),
22 };
23 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
24 let tag = get_tag(&input.into());
25 quote! {
26 unsafe impl #impl_generics ::pyo3_commonize::Commonized for #ident #ty_generics #where_clause {
27 const __COMMONIZED_INTERNAL_TAG: usize = #tag;
28 const __COMMONIZED_MODPATH: &'static str = ::core::module_path!();
29 const __COMMONIZED_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
30 }
31 }
32 .into()
33}