-
Notifications
You must be signed in to change notification settings - Fork 263
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be7d362
commit 37bcf14
Showing
16 changed files
with
666 additions
and
411 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "noclip-macros" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
proc-macro2 = "1.0.89" | ||
quote = "1.0.37" | ||
syn = { version = "2.0.87", features = ["extra-traits"] } |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use syn::{Attribute, Data, Path}; | ||
use quote::quote; | ||
|
||
#[proc_macro_derive(FromStructPerField, attributes(from))] | ||
pub fn derive_from_struct_per_field(item: proc_macro::TokenStream) -> proc_macro::TokenStream { | ||
let input = syn::parse_macro_input!(item as syn::DeriveInput); | ||
|
||
let mut from_structs = Vec::new(); | ||
for attr in &input.attrs { | ||
match &attr.meta { | ||
syn::Meta::List(meta_list) => { | ||
let tokens: proc_macro::TokenStream = meta_list.tokens.clone().into(); | ||
from_structs.push(syn::parse_macro_input!(tokens as syn::Path)); | ||
}, | ||
_ => unimplemented!(), | ||
}; | ||
} | ||
|
||
let struct_identifier = &input.ident; | ||
let mut impls = proc_macro2::TokenStream::new(); | ||
|
||
match &input.data { | ||
Data::Struct(syn::DataStruct { fields, .. }) => { | ||
let mut field_assignments = proc_macro2::TokenStream::new(); | ||
for field in fields { | ||
let identifier = field.ident.as_ref().unwrap(); | ||
field_assignments.extend(quote!{ | ||
#identifier: value.#identifier.into(), | ||
}); | ||
} | ||
|
||
for from_struct in from_structs { | ||
impls.extend(quote!{ | ||
impl From<#from_struct> for #struct_identifier { | ||
fn from(value: #from_struct) -> #struct_identifier { | ||
#struct_identifier { | ||
#field_assignments | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
_ => unimplemented!(), | ||
} | ||
|
||
impls.into() | ||
} | ||
|
||
#[proc_macro_derive(FromEnumPerVariant, attributes(from))] | ||
pub fn derive_from_enum(item: proc_macro::TokenStream) -> proc_macro::TokenStream { | ||
let input = syn::parse_macro_input!(item as syn::DeriveInput); | ||
|
||
let mut from_enums = Vec::new(); | ||
for attr in &input.attrs { | ||
match &attr.meta { | ||
syn::Meta::List(meta_list) => { | ||
let tokens: proc_macro::TokenStream = meta_list.tokens.clone().into(); | ||
from_enums.push(syn::parse_macro_input!(tokens as syn::Path)); | ||
}, | ||
_ => unimplemented!(), | ||
}; | ||
} | ||
|
||
let enum_identifier = &input.ident; | ||
let mut impls = proc_macro2::TokenStream::new(); | ||
|
||
match &input.data { | ||
Data::Enum(syn::DataEnum { variants, .. }) => { | ||
for from_enum in from_enums { | ||
let mut variant_patterns = proc_macro2::TokenStream::new(); | ||
for variant in variants { | ||
let identifier = &variant.ident; | ||
variant_patterns.extend(quote!{ | ||
#from_enum::#identifier => #enum_identifier::#identifier, | ||
}); | ||
} | ||
|
||
impls.extend(quote!{ | ||
impl From<#from_enum> for #enum_identifier { | ||
fn from(value: #from_enum) -> #enum_identifier { | ||
match value { | ||
#variant_patterns | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
_ => unimplemented!(), | ||
} | ||
|
||
impls.into() | ||
} | ||
|
||
#[proc_macro_attribute] | ||
pub fn from(attr: proc_macro::TokenStream, _: proc_macro::TokenStream) -> proc_macro::TokenStream { | ||
attr | ||
} |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
pub mod v2019_4_39f1; | ||
pub mod v2020_3_16f1; | ||
pub mod v2021_3_27f1; | ||
pub mod object; |
Oops, something went wrong.