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