Skip to main content

xwrapup_derive/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::{format_ident, quote};
5use syn::{parse_macro_input, DeriveInput};
6
7#[proc_macro_derive(DsRef)]
8pub fn ds_ref_derive_macro(input: TokenStream) -> TokenStream {
9    let input = parse_macro_input!(input as DeriveInput);
10    let name = input.ident;
11    let ref_name = format_ident!("{}Ref", name);
12
13    let expanded = quote! {
14        impl #name {
15            pub fn into_ref(self) -> #ref_name {
16                #ref_name {
17                    inner: std::rc::Rc::new(core::cell::RefCell::new(self)),
18                }
19            }
20        }
21
22        #[derive(Debug)]
23        pub struct #ref_name {
24            inner: std::rc::Rc<core::cell::RefCell<#name>>,
25        }
26
27        impl Clone for #ref_name {
28            fn clone(&self) -> Self {
29                #ref_name {
30                    inner: self.inner.clone(),
31                }
32            }
33        }
34
35        impl core::ops::Deref for #ref_name {
36            type Target = std::rc::Rc<std::cell::RefCell<#name>>;
37
38            fn deref(&self) -> &Self::Target {
39                &self.inner
40            }
41        }
42
43        impl core::ops::DerefMut for #ref_name {
44            fn deref_mut(&mut self) -> &mut Self::Target {
45                &mut self.inner
46            }
47        }
48    };
49
50    TokenStream::from(expanded)
51}