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 51 52 53 54 55 56 57
#![recursion_limit="128"] extern crate proc_macro; mod parse_rcstruct; use self::parse_rcstruct::RcStruct; #[proc_macro] pub fn rcstruct(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let RcStruct { span, vis, ident, inner_ident, fields_named, new_vis, new_args, new_output, new_stmts, new_init, impl_methods, wrap_methods, } = syn::parse_macro_input!(input); let output = quote::quote_spanned! { span=> struct #inner_ident { rcstruct_outer: std::rc::Weak<std::cell::RefCell<#inner_ident>>, #fields_named } impl #inner_ident { #(#impl_methods)* } #[derive(Clone)] #vis struct #ident(std::rc::Rc<std::cell::RefCell<#inner_ident>>); impl #ident { #new_vis fn new(#new_args) #new_output { #(#new_stmts)* let rcstruct_rc = std::rc::Rc::new(std::cell::RefCell::new(#inner_ident { rcstruct_outer: std::rc::Weak::new(), #new_init })); rcstruct_rc.borrow_mut().rcstruct_outer = std::rc::Rc::downgrade(&rcstruct_rc); Ok(#ident(rcstruct_rc)) } #(#wrap_methods)* } }; let output = output.into(); output }