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}