pyo3_commonize_macro/
lib.rs

1use 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}