Last active
February 2, 2024 17:43
-
-
Save uvicorn/0bd4cf624944709c3cb8193aca9ad529 to your computer and use it in GitHub Desktop.
Add fields\functions to struct && add implementations of functions in the implementation of a trait by a structure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use proc_macro::TokenStream; | |
use quote::quote; | |
use syn::{parse_macro_input, ItemImpl}; | |
#[proc_macro_attribute] | |
pub fn DefaultTraitImpl(args: TokenStream, input: TokenStream) -> TokenStream { | |
let ii= parse_macro_input!(input as ItemImpl); | |
let a = &ii.attrs; // avtor dolboyoba, ne obrazhiaite vnimanii | |
let u = &ii.unsafety; | |
let s = &ii.self_ty; | |
let (ba, pa, fo) = ii.trait_.unwrap(); // bang, path, for tokens | |
let g = &ii.generics; | |
let i = &ii.impl_token; | |
let it = &ii.items; | |
let d = &ii.defaultness; | |
return quote! { | |
#(#a)* | |
#d #u #i #g #ba #pa #fo #s { // default unsafe impl<'a, T> ! MyTrait for User | |
#(#it)* | |
fn get_id(&self) -> i8{ | |
1 | |
} | |
} | |
} | |
.into(); | |
} | |
/* | |
trait MyTrait { | |
fn get_id(&self) -> i8; | |
fn new_i8() -> i8; | |
} | |
struct User{} | |
#[DefaultTraitImpl] | |
impl MyTrait for User { | |
fn new_i8() -> i8 { | |
2 | |
} | |
} | |
let user = User {}; | |
println!("{}", user.get_id()); // 1 | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use proc_macro::TokenStream; | |
use quote::quote; | |
use syn::parse::Parser; | |
use syn::{parse, parse_macro_input, ItemStruct}; | |
use proc_macro2::{Ident, Span}; | |
use syn::parse::Parser; | |
#[proc_macro_attribute] | |
pub fn BaseObject(args: TokenStream, input: TokenStream) -> TokenStream { | |
let mut item_struct = parse_macro_input!(input as ItemStruct); | |
let _ = parse_macro_input!(args as parse::Nothing); | |
let fields_to_add = vec![quote!{field: i8 }]; // Insert quote!{ Field: Type } | |
let name = &item_struct.ident; | |
if let syn::Fields::Named(ref mut fields) = item_struct.fields { | |
for f in fields_to_add{ | |
fields.named.push( | |
syn::Field::parse_named | |
.parse2(f) | |
.unwrap(), | |
); | |
} | |
} | |
let name_low = Ident::new(&(name.to_string().to_lowercase())[..], Span::call_site()); // example of creating Ident | |
return quote! { | |
#item_struct | |
impl #name { | |
pub fn print_field(&self) { | |
println!("Struct {} has field equal to {}", #name_low , self.field; // println!("#name_low") will print #name_low, not its value | |
} | |
} | |
} | |
.into(); | |
} | |
/* | |
#[BaseObject] | |
struct MyStruct { | |
new_field: i16 | |
} | |
let my = MyStruct { field: 1, field16: 2}; | |
my.print_field(); // Struct mystruct has field equal to 1 | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "libmacro" | |
version = "0.1.0" | |
edition = "2018" | |
publish = false | |
[lib] | |
proc-macro = true | |
[dependencies] | |
syn = { version = "1.0", features = ["full"] } | |
quote = "1.0" | |
proc-macro2 = "1.0" | |
macroquad = "0.3" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After a lot of searching, finally found a working macro example to add a field to a struct, thank you for this!