oop_macro/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenTree;
3use quote::quote;
4use syn::{parse_macro_input, ItemStruct, parse::Parse, Type};
5
6struct ExtendArgs {
7	target: Box<Type>,
8	field_name: TokenTree,
9}
10
11impl Parse for ExtendArgs {
12    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
13        let target = input.parse()?;
14		input.parse::<syn::Token![,]>()?;
15		let field_name = input.parse()?;
16		Ok(
17			Self {
18				target,
19				field_name,
20			}
21		)
22    }
23}
24
25#[proc_macro_attribute]
26pub fn extend(attr: TokenStream, mut item: TokenStream) -> TokenStream {
27	let item2 = item.clone();
28	let input = parse_macro_input!(item2 as ItemStruct);
29	let args = parse_macro_input!(attr as ExtendArgs);
30	
31	let struct_name = input.ident;
32	let target = args.target;
33	let field_name = args.field_name;
34	item.extend::<TokenStream>(
35		quote! {
36			impl ::core::ops::Deref for #struct_name {
37				type Target = #target;
38				
39				fn deref(&self) -> &Self::Target {
40					&self.#field_name
41				}
42			}
43			
44			impl ::core::ops::DerefMut for #struct_name {
45				fn deref_mut(&mut self) -> &mut Self::Target {
46					&mut self.#field_name
47				}
48			}
49			
50			impl #struct_name {
51				pub fn _super(&self) -> &#target {
52					<Self as ::core::ops::Deref>::deref(self)
53				}
54				
55				pub fn _super_mut(&mut self) -> &mut #target {
56					<Self as ::core::ops::DerefMut>::deref_mut(self)
57				}
58			}
59		}.into()
60	);
61	
62	item
63}