1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
extern crate proc_macro; extern crate syn; #[macro_use] extern crate quote; use proc_macro::TokenStream; use quote::TokenStreamExt; #[proc_macro_derive(SafeUninit)] pub fn derive_answer_fn(item: TokenStream) -> TokenStream { let mut st = syn::parse_macro_input!(item as syn::ItemStruct); let ident = &st.ident; let fields = &mut st.fields; let mut tok = quote!(); let mut is_named = true; for f in fields { if let Some(name) = f.ident.as_ref() { tok.append_all(quote!(#name: safe_uninit::SafeUninit::safe_uninit(),)); is_named = true; } else { is_named = false; tok.append_all(quote!(safe_uninit::SafeUninit::safe_uninit(),)); } } let tok = if is_named { quote!({#tok}) } else { quote!((#tok)) }; quote!( unsafe impl safe_uninit::SafeUninit for #ident { fn safe_uninit() -> Self { #ident #tok } } ).into() } #[cfg(test)] mod test { #[test] fn derive0() { let t = trybuild::TestCases::new(); t.pass("src/tests/pass.rs"); t.compile_fail("src/tests/fail.rs"); } }