From e2a012c7b108927fcc41a735a850f821e5151aff Mon Sep 17 00:00:00 2001 From: hodasemi Date: Mon, 20 Feb 2023 10:14:23 +0100 Subject: [PATCH] Add backup lost things from backup --- Cargo.toml | 5 ++- src/lib.rs | 3 ++ src/prelude.rs | 3 ++ src/repr_c.rs | 23 ++++++++++++ src/reprc_proc_macro/Cargo.toml | 13 +++++++ src/reprc_proc_macro/src/lib.rs | 62 +++++++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 src/repr_c.rs create mode 100644 src/reprc_proc_macro/Cargo.toml create mode 100644 src/reprc_proc_macro/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index f967a9c..4bdb3f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,12 @@ authors = ["hodasemi "] edition = "2021" [dependencies] -cgmath = { version = "0.18.0" } +cgmath = { version = "0.18.0", features = ["swizzle", "serde"] } 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"] } - - diff --git a/src/lib.rs b/src/lib.rs index 878d738..2e8dca8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/prelude.rs b/src/prelude.rs index b19f64d..4be0e39 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -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; diff --git a/src/repr_c.rs b/src/repr_c.rs new file mode 100644 index 0000000..4d6e13b --- /dev/null +++ b/src/repr_c.rs @@ -0,0 +1,23 @@ +#[macro_export] +macro_rules! impl_reprc { + ( + $(#[$meta: meta])* + $v:vis struct $struct_name:ident { + $( $(#[$field_meta:meta])* $member:ident : $t:ty, )+ + } + ) => { + #[repr(C)] + #[derive(Clone, DeriveReprC)] + $(#[$meta])* + $v struct $struct_name { + $( + $( #[$field_meta] )* + pub $member: $t, + )+ + } + }; +} + +pub unsafe trait ReprC { + fn is_repr_c(&self) -> bool; +} diff --git a/src/reprc_proc_macro/Cargo.toml b/src/reprc_proc_macro/Cargo.toml new file mode 100644 index 0000000..3f44c9e --- /dev/null +++ b/src/reprc_proc_macro/Cargo.toml @@ -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" \ No newline at end of file diff --git a/src/reprc_proc_macro/src/lib.rs b/src/reprc_proc_macro/src/lib.rs new file mode 100644 index 0000000..d7a6768 --- /dev/null +++ b/src/reprc_proc_macro/src/lib.rs @@ -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 = 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 as &dyn ReprC) .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"), + } +}