just playing with tangled
at globpattern 38 lines 1.3 kB view raw
1mod content_hash; 2 3extern crate proc_macro; 4 5use quote::quote; 6use syn::parse_macro_input; 7use syn::DeriveInput; 8 9/// Derive macro generating an impl of the trait `ContentHash`. 10/// 11/// Derives the `ContentHash` trait for a struct by calling `ContentHash::hash` 12/// on each of the struct members in the order that they're declared. All 13/// members of the struct must implement the `ContentHash` trait. 14#[proc_macro_derive(ContentHash)] 15pub fn derive_content_hash(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 16 let input = parse_macro_input!(input as DeriveInput); 17 18 // The name of the struct. 19 let name = &input.ident; 20 21 // Generate an expression to hash each of the fields in the struct. 22 let hash_impl = content_hash::generate_hash_impl(&input.data); 23 24 // Handle structs and enums with generics. 25 let generics = content_hash::add_trait_bounds(input.generics); 26 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); 27 28 let expanded = quote! { 29 #[automatically_derived] 30 impl #impl_generics ::jj_lib::content_hash::ContentHash for #name #ty_generics 31 #where_clause { 32 fn hash(&self, state: &mut impl digest::Update) { 33 #hash_impl 34 } 35 } 36 }; 37 expanded.into() 38}