Add custom macro for ReprC impl
This commit is contained in:
parent
f34f5974ac
commit
b5af5fbe70
6 changed files with 118 additions and 0 deletions
|
@ -10,6 +10,7 @@ rand = "0.8.5"
|
|||
backtrace = "0.3.67"
|
||||
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||
anyhow = { version = "1.0.68", features = ["backtrace"] }
|
||||
reprc_proc_macro = { path = "src/reprc_proc_macro" }
|
||||
|
||||
# networking
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
|
|
|
@ -14,4 +14,7 @@ pub mod try_lock_guard;
|
|||
pub mod arc_unique_vec;
|
||||
pub mod rc_unique_vec;
|
||||
|
||||
#[macro_use]
|
||||
mod repr_c;
|
||||
|
||||
pub mod unsafe_life_time;
|
||||
|
|
|
@ -27,3 +27,6 @@ pub use crate::try_lock_guard::TryLockGuard;
|
|||
|
||||
// unsafe life time trickery
|
||||
pub use crate::unsafe_life_time::*;
|
||||
|
||||
pub use crate::repr_c::ReprC;
|
||||
pub use reprc_proc_macro::DeriveReprC;
|
||||
|
|
36
src/repr_c.rs
Normal file
36
src/repr_c.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use reprc_proc_macro::DeriveReprC;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_reprc {
|
||||
(
|
||||
$(#[$meta: meta])*
|
||||
$v:vis struct $struct_name:ident {
|
||||
$( $(#[$field_meta:meta])* $member:ident : $t:ty, )+
|
||||
}
|
||||
) => {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, DeriveReprC)]
|
||||
$(#[$meta])*
|
||||
$v struct $struct_name {
|
||||
$(
|
||||
$( #[$field_meta] )*
|
||||
pub $member: $t,
|
||||
)+
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_reprc!(
|
||||
struct Test {
|
||||
#[assume_reprc]
|
||||
i1: i32,
|
||||
#[assume_reprc]
|
||||
i2: i32,
|
||||
#[assume_reprc]
|
||||
v1: Vec<i32>,
|
||||
}
|
||||
);
|
||||
|
||||
pub unsafe trait ReprC {
|
||||
fn is_repr_c(&self) -> bool;
|
||||
}
|
13
src/reprc_proc_macro/Cargo.toml
Normal file
13
src/reprc_proc_macro/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "reprc_proc_macro"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1.0.107", features = ["full", "fold"] }
|
||||
quote = "1.0.23"
|
62
src/reprc_proc_macro/src/lib.rs
Normal file
62
src/reprc_proc_macro/src/lib.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{parse_macro_input, Data, DeriveInput, Ident};
|
||||
|
||||
const REPRC_ATTRIBUTE: &'static str = "assume_reprc";
|
||||
|
||||
#[proc_macro_derive(DeriveReprC, attributes(assume_reprc))]
|
||||
pub fn reprc_builder(item: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(item as DeriveInput);
|
||||
|
||||
let struct_name = ast.ident;
|
||||
let generics = ast.generics.to_token_stream();
|
||||
|
||||
match ast.data {
|
||||
Data::Struct(data_struct) => match data_struct.fields {
|
||||
syn::Fields::Named(named_fields) => {
|
||||
let reprc_fields: Vec<Ident> = named_fields
|
||||
.named
|
||||
.iter()
|
||||
.filter_map(|field| {
|
||||
if field
|
||||
.attrs
|
||||
.iter()
|
||||
.find(|attribute| {
|
||||
let segments = &attribute.path.segments;
|
||||
|
||||
if segments.len() < 1 {
|
||||
return false;
|
||||
}
|
||||
|
||||
segments[0].ident == REPRC_ATTRIBUTE
|
||||
})
|
||||
.is_some()
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(field.ident.clone())
|
||||
}
|
||||
})
|
||||
.map(|i| i.unwrap())
|
||||
.collect();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
unsafe impl #generics ReprC for #struct_name #generics {
|
||||
fn is_repr_c(&self) -> bool {
|
||||
true
|
||||
|
||||
#(
|
||||
&& self. #reprc_fields.to_tokens() .is_repr_c()
|
||||
)*
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
syn::Fields::Unnamed(_) => todo!("Unnamed Field not supported"),
|
||||
syn::Fields::Unit => todo!("Unit not supported"),
|
||||
},
|
||||
|
||||
Data::Enum(_) => todo!("Enum not supported"),
|
||||
Data::Union(_) => todo!("Union not supported"),
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue