From 6d1c62680473d75cc721dfcc10c91ebf0f6c6091 Mon Sep 17 00:00:00 2001 From: cat_or_not <41955154+catornot@users.noreply.github.com> Date: Sun, 7 Jan 2024 15:27:05 -0500 Subject: [PATCH] add source interfaces --- Cargo.lock | 34 ++-- Cargo.toml | 7 +- rrplug_proc/Cargo.lock | 74 --------- rrplug_proc/src/impl_traits.rs | 28 ++-- rrplug_proc/src/lib.rs | 289 ++++++++++++++++++++++++++------- rrplug_proc/src/parsing.rs | 18 +- src/lib.rs | 3 +- 7 files changed, 284 insertions(+), 169 deletions(-) delete mode 100644 rrplug_proc/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index fcdc897..76973ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "lock_api" @@ -44,9 +44,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" @@ -73,18 +73,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "rrplug" -version = "3.0.0" +version = "4.0.0" dependencies = [ "log", "once_cell", @@ -126,15 +126,15 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -143,18 +143,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index d91a634..6cbb77d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rrplug" -version = "3.0.0" +version = "4.0.0" authors = ["catornot"] description = "wrappers and functions for R2Northstar plugins" repository = "https://github.com/catornot/rrplug" @@ -23,6 +23,5 @@ default-target = "x86_64-pc-windows-msvc" targets = ["x86_64-pc-windows-msvc"] [features] -default = ["default_features"] -default_features = [ ] -full = [ ] \ No newline at end of file +default = [] +async_engine = [] diff --git a/rrplug_proc/Cargo.lock b/rrplug_proc/Cargo.lock deleted file mode 100644 index b615be3..0000000 --- a/rrplug_proc/Cargo.lock +++ /dev/null @@ -1,74 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "const_format" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "proc-macro2" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rrplug_proc" -version = "2.1.1" -dependencies = [ - "const_format", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" diff --git a/rrplug_proc/src/impl_traits.rs b/rrplug_proc/src/impl_traits.rs index 7fa2004..8de050f 100644 --- a/rrplug_proc/src/impl_traits.rs +++ b/rrplug_proc/src/impl_traits.rs @@ -37,7 +37,7 @@ pub fn get_from_sqvm_impl_struct(input: DeriveInput) -> TokenStream { stack_pos: i32, ) -> Self { use rrplug::{high::squirrel_traits::GetFromSQObject,bindings::squirreldatatypes::SQObject}; - let sqstruct = unsafe { + let sqstruct = unsafe { let sqvm = sqvm.as_ref().expect("sqvm has to be valid"); ((*sqvm._stackOfCurrentFunction.add(stack_pos as usize)) ._VAL @@ -129,9 +129,9 @@ pub fn get_from_sqvm_impl_enum(input: DeriveInput) -> TokenStream { sqvm: *mut HSquirrelVM, sqfunctions: &SquirrelFunctionsUnwraped, stack_pos: i32, - ) -> Self { + ) -> Self { const _ :#ident<#generics> = unsafe { std::mem::transmute::>(0) }; - + let value = unsafe { rrplug::mid::squirrel::get_sq_int(sqvm, sqfunctions, stack_pos) }; if value >= #ident::#varient_first as i32 && value <= #ident::#varient_last as i32 { @@ -197,7 +197,7 @@ pub fn get_from_sqobject_impl_enum(input: DeriveInput) -> TokenStream { #[allow(clippy::not_unsafe_ptr_arg_deref)] fn get_from_sqobject(obj: &rrplug::bindings::squirreldatatypes::SQObject) -> Self { const _: #ident<#generics> = unsafe { std::mem::transmute::>(0) }; - + let value = unsafe { obj._VAL.asInteger }; if value >= #ident::#varient_first as i32 && value <= #ident::#varient_last as i32 { @@ -214,13 +214,14 @@ pub fn get_from_sqobject_impl_enum(input: DeriveInput) -> TokenStream { // TODO: refactor this to use what I have in the other implemantion of this // whar, past self? pub fn get_from_sqobject_impl_struct(input: DeriveInput) -> TokenStream { - let DeriveInput { // copying this from system clipboard destroyed this, but I won't fix this today - attrs: _, - vis: _, - ident, - generics, - data, - } = input; + let DeriveInput { + // copying this from system clipboard destroyed this, but I won't fix this today + attrs: _, + vis: _, + ident, + generics, + data, + } = input; let fields = get_struct_fields(data); let field_idents: Vec = fields.iter().cloned().filter_map(|f| f.ident).collect(); let field_amount = field_idents.len() as u32; @@ -229,8 +230,8 @@ pub fn get_from_sqobject_impl_struct(input: DeriveInput) -> TokenStream { #[allow(clippy::not_unsafe_ptr_arg_deref)] // smth should be done about this #[inline] fn get_from_sqobject(obj: &rrplug::bindings::squirreldatatypes::SQObject) -> Self { - use rrplug::{high::squirrel_traits::GetFromSQObject,bindings::squirreldatatypes::SQObject}; - let sqstruct = unsafe { + use rrplug::{high::squirrel_traits::getfromsqobject,bindings::squirreldatatypes::sqobject}; + let sqstruct = unsafe { obj ._VAL .asStructInstance @@ -253,7 +254,6 @@ pub fn get_from_sqobject_impl_struct(input: DeriveInput) -> TokenStream { .into() } - pub fn sqvm_name_impl(input: DeriveInput) -> TokenStream { let DeriveInput { attrs: _, diff --git a/rrplug_proc/src/lib.rs b/rrplug_proc/src/lib.rs index c384949..31a8741 100644 --- a/rrplug_proc/src/lib.rs +++ b/rrplug_proc/src/lib.rs @@ -1,41 +1,48 @@ extern crate proc_macro; use proc_macro::TokenStream; -use quote::{format_ident, quote, ToTokens}; +use proc_macro2::Span; +use quote::{format_ident, quote, quote_spanned, ToTokens}; use syn::{ - self, parse_macro_input, DeriveInput, FnArg, Ident, ItemFn, Stmt, Error as SynError, Type, parse_str + self, parse_macro_input, parse_str, punctuated::Punctuated, spanned::Spanned, + AngleBracketedGenericArguments, DeriveInput, Error as SynError, FnArg, Ident, ImplItem, + ImplItemFn, ItemFn, ItemImpl, ReturnType, Stmt, Token, Type, }; #[macro_use] pub(crate) mod parsing; pub(crate) mod impl_traits; -use impl_traits::{sqvm_name_impl, impl_struct_or_enum, push_to_sqvm_impl_struct, push_to_sqvm_impl_enum, get_from_sqvm_impl_enum, get_from_sqvm_impl_struct, get_from_sqobject_impl_enum, get_from_sqobject_impl_struct}; -use parsing::{filter_args, input_mapping, Args}; +use impl_traits::{ + get_from_sqobject_impl_enum, get_from_sqobject_impl_struct, get_from_sqvm_impl_enum, + get_from_sqvm_impl_struct, impl_struct_or_enum, push_to_sqvm_impl_enum, + push_to_sqvm_impl_struct, sqvm_name_impl, +}; +use parsing::{filter_args, get_arg_ident, input_mapping, Args}; // TODO: add multiple vm targets to sqfunction -/// proc marco for generating compatible functions with the sqvm. +/// proc marco for generating compatible functions with the sqvm. /// /// ## abstractions /// the macro uses arguments types and return types to tranlates them into a sqfunction deffintion /// `GetFromSquirrelVm` and `PushToSquirrelVm` define logic for how -/// +/// /// ## attributes /// - **VM** -/// +/// /// Indicates for which the sqfunction is created /// .The default is `Client` /// - **ExportName** -/// +/// /// Specifies the name for the function on the sqvm /// - **ReturnOverwrite** -/// +/// /// Overwrites the return type for the sqfunction definition /// Useful for ensuring type safety for custom structs and other custom types since they default to `var`. /// ## Traits /// this macro heavily relies on traits from rrplug and only exists to generate a parsing code. -/// +/// /// refer to the traits for more info #[proc_macro_attribute] pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { @@ -55,13 +62,16 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { let ident = &sig.ident; let input = &sig.inputs; let input_vec: Vec = input.iter().filter_map(|arg| filter_args(arg)).collect(); - let input_type_names = input_vec.iter().filter_map(|_input| { - if let FnArg::Typed(t) = _input { - Some(t) - } else { - None - } - }).map(|arg| arg.ty.as_ref()); + let input_type_names = input_vec + .iter() + .filter_map(|_input| { + if let FnArg::Typed(t) = _input { + Some(t) + } else { + None + } + }) + .map(|arg| arg.ty.as_ref()); let input_var_names: Vec = input .iter() .cloned() @@ -90,13 +100,15 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { let mut sq_gets_stmts = Vec::new(); let mut out: Box = match output { - syn::ReturnType::Default => match parse_str::("()").map_err(|err| err.to_compile_error().into()) { - Ok(v) => Box::new(v), - Err(err) => return err, - }, + syn::ReturnType::Default => { + match parse_str::("()").map_err(|err| err.to_compile_error().into()) { + Ok(v) => Box::new(v), + Err(err) => return err, + } + } syn::ReturnType::Type(_, ty) => ty.clone(), }; - + match input_mapping(input, &mut sq_stack_pos) { Ok(tks) => { for tk in tks { @@ -135,22 +147,23 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { script_vm_func = "client"; } "VM" => { - return SynError::new( - arg.ident.span(), - format!("invalid VM {}", input) - ).to_compile_error() - .into(); + return SynError::new(arg.ident.span(), format!("invalid VM {}", input)) + .to_compile_error() + .into(); } "ExportName" => export_name = input, - "ReturnOverwrite" => out = match parse_str::(&input).map_err(|err| err.to_compile_error().into()) { - Ok(v) => Box::new(v), - Err(err) => return err, - }, + "ReturnOverwrite" => { + out = match parse_str::(&input).map_err(|err| err.to_compile_error().into()) { + Ok(v) => Box::new(v), + Err(err) => return err, + } + } _ => { return SynError::new( arg.ident.span(), - format!("wrong arg \"{}\" or arg {}", input, arg.ident.to_string()) - ).to_compile_error() + format!("wrong arg \"{}\" or arg {}", input, arg.ident.to_string()), + ) + .to_compile_error() .into(); } } @@ -166,18 +179,18 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { let sq_functions = SQFUNCTIONS.#script_vm_func.wait(); #(#sub_stms)* - + fn inner_function( sqvm: *mut rrplug::bindings::squirreldatatypes::HSquirrelVM, sq_functions: &SquirrelFunctionsUnwraped #(, #input_vec)* ) #output { #(#stmts)* } inner_function( sqvm, sq_functions #(, #input_var_names)* ).return_to_vm(sqvm, sq_functions) } - + #(#attrs)* #vis fn #ident () -> rrplug::high::northstar::SQFuncInfo { use rrplug::high::squirrel_traits::SQVMName; - + let mut types = String::new(); #( if ( !types.is_empty() ) { @@ -189,12 +202,12 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { types.push_str(stringify!(#input_var_names)); )* - rrplug::high::northstar::SQFuncInfo{ - cpp_func_name: #func_name, - sq_func_name: #export_name, + rrplug::high::northstar::SQFuncInfo{ + cpp_func_name: #func_name, + sq_func_name: #export_name, types: types, - return_type: <#out as SQVMName>::get_sqvm_name(), - vm: ScriptVmType::#script_vm_type, + return_type: <#out as SQVMName>::get_sqvm_name(), + vm: ScriptVmType::#script_vm_type, function: Some( #sq_functions_func ), } } @@ -204,14 +217,14 @@ pub fn sqfunction(attr: TokenStream, item: TokenStream) -> TokenStream { } /// proc marco for generating compatible concommand callbacks -/// +/// /// this macro wraps your function in another function and tries to provide the argurments your requested -/// +/// /// # how to use it /// the 2 possible function signatures are /// - `fn(CCommandResult)` /// - `fn()` -/// +/// /// the result is ignored so it can be anything #[proc_macro_attribute] pub fn concommand(_attr: TokenStream, item: TokenStream) -> TokenStream { @@ -256,14 +269,14 @@ pub fn concommand(_attr: TokenStream, item: TokenStream) -> TokenStream { } /// proc marco for generating compatible concommand callbacks -/// +/// /// this macro wraps your function in another function and tries to provide the argurments your requested -/// +/// /// # how to use it /// the 2 possible function signatures are /// - `fn(String, f32)` /// - `fn()` -/// +/// /// the result is ignored so it can be anything #[proc_macro_attribute] pub fn convar(_attr: TokenStream, item: TokenStream) -> TokenStream { @@ -311,10 +324,170 @@ pub fn convar(_attr: TokenStream, item: TokenStream) -> TokenStream { .into() } +#[proc_macro_attribute] +pub fn as_interface(_attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as ItemImpl); + let ItemImpl { + attrs, + defaultness: _, + unsafety: _, + impl_token, + generics, + trait_, + self_ty, + brace_token: _, + items, + } = input; + + let self_ty_ident: Type = match parse_str( + self_ty + .to_token_stream() + .to_string() + .split('<') + .nth(0) + .unwrap(), + ) { + Ok(ty) => ty, + Err(err) => return err.to_compile_error().into(), + }; + let generics_bracked: Option = self_ty + .to_token_stream() + .to_string() + .split_once('<') + .map(|(_, generics)| format!("<{}>", generics)) + .map(|generic_str| parse_str(&generic_str).ok()) + .flatten(); + + if let Some(trait_) = trait_ { + let error_site = trait_.1.span(); + return quote_spanned! {error_site => compile_error!("interfaces must not be a implementation for a trait");}.into(); + } + + let mut funcs = match items + .into_iter() + .map(|item| match (item.span(), item) { + (_, ImplItem::Fn(func)) => Ok(func), + (span, _) => Err(span), + }) + .collect::, Span>>() + { + Ok(funcs) => funcs, + Err(error_site) => { + return quote_spanned! {error_site => compile_error!("can only have functions in interfaces");}.into() + } + }; + + let new_impl = match funcs + .iter() + .find(|func| func.sig.ident.to_string() == "new") + .map(|func| func.block.stmts.clone()) + { + Some(funcs) => funcs, + None => { + return quote! {compile_error!("a interface must have a new function to initialize it");} + .into() + } + }; + + funcs.remove( + funcs + .iter() + .position(|func| func.sig.ident.to_string() == "new") + .unwrap(), + ); + + if funcs.is_empty() { + return quote! {compile_error!("perhaps you should add a function to your interface");} + .into(); + } + + let function_idents = funcs + .iter() + .map(|func| &func.sig.ident) + .collect::>(); + + if let Some(error_site) = funcs + .iter() + .find(|func| { + func.sig + .inputs + .first() + .map(|selfarg| match selfarg { + FnArg::Receiver(_) => Some(()), + _ => None, + }) + .flatten() + .is_none() + }) + .map(|func| func.sig.inputs.span()) + { + return quote_spanned! {error_site => compile_error!("functions must have &self");}.into(); + } + + let extern_inputs = funcs + .iter() + .map(|func| { + func.sig + .inputs + .iter() + .skip(1) + .collect::>() + }) + .collect::>>(); + let extern_inputs_idents = extern_inputs + .iter() + .map(|inputs| { + inputs.iter().filter_map(|input| get_arg_ident(input)).fold( + Punctuated::new(), + |mut acc, ident| { + acc.push(ident); + acc + }, + ) + }) + .collect::>>(); + let extern_outputs = funcs + .iter() + .map(|func| &func.sig.output) + .collect::>(); + + quote! { + #(#attrs)* + #impl_token #generics #self_ty { + #(#funcs)* + } + + #(#attrs)* + impl #generics rrplug::interfaces::interface::AsInterface for #self_ty { + fn as_interface() -> rrplug::interfaces::interface::Interface { + // make these extern c wrapped and offset the self since it will have the vtable + // TODO: make generic functions work (big headache) + #( + #[allow(unsafe_op_in_unsafe_fn)] + unsafe extern "C" fn #function_idents #generics(self_: *const std::ffi::c_void, #extern_inputs) #extern_outputs { + // transmute because I want to be lazy here + #self_ty_ident::#generics_bracked #function_idents(std::mem::transmute(self_.offset(std::mem::size_of::() as isize)), #extern_inputs_idents ) + } + )* + + const VTABLE: &[*const std::ffi::c_void] = &[#(#function_idents #generics_bracked as *const std::ffi::c_void,)*]; + + rrplug::interfaces::interface::Interface::new( + unsafe { std::ptr::NonNull::new_unchecked(VTABLE.as_ptr().cast_mut()) }, + { + #(#new_impl)* + } + ) + } + } + } + .into() +} + /// implements `GetFromSquirrelVm` for structs or enums -/// +/// /// the fields of the struct must implement `GetFromSQObject` -/// +/// /// the enum must be unit-only #[proc_macro_derive(GetFromSquirrelVm)] pub fn get_from_sqvm_macro(item: TokenStream) -> TokenStream { @@ -324,9 +497,9 @@ pub fn get_from_sqvm_macro(item: TokenStream) -> TokenStream { } /// implements `PushToSquirrelVm` for structs or enums -/// +/// /// the fields of the struct must implement `PushToSquirrelVm` -/// +/// /// the enum must be unit-only #[proc_macro_derive(PushToSquirrelVm)] pub fn push_to_sqvm_macro(item: TokenStream) -> TokenStream { @@ -336,20 +509,24 @@ pub fn push_to_sqvm_macro(item: TokenStream) -> TokenStream { } /// macro to auto generate a `GetFromSQObject` implementation for enums and structs behaves mostly like `GetFromSquirrelVm` -/// +/// /// since squirrel's enums are integers the enum must be a unit-only enum -/// +/// /// maybe also use `#[repr(i32)]` idk #[proc_macro_derive(GetFromSQObject)] pub fn get_from_sqobject_macro(item: TokenStream) -> TokenStream { let input = parse_macro_input!(item as DeriveInput); - impl_struct_or_enum(input, get_from_sqobject_impl_struct, get_from_sqobject_impl_enum) + impl_struct_or_enum( + input, + get_from_sqobject_impl_struct, + get_from_sqobject_impl_enum, + ) } /// macro to auto generate a `SQVMName` implementation -/// -/// the implementation will just be the name of the struct/enum so if the squirrel name is diffrent use a util macro in `rrplug::macro::utils` +/// +/// the implementation will just be the name of the struct/enum so if the squirrel name is diffrent use a util macro in `rrplug::macro::utils` #[proc_macro_derive(SQVMName)] pub fn sqvm_name_macro(item: TokenStream) -> TokenStream { let input = parse_macro_input!(item as DeriveInput); diff --git a/rrplug_proc/src/parsing.rs b/rrplug_proc/src/parsing.rs index a5ac612..bf76811 100644 --- a/rrplug_proc/src/parsing.rs +++ b/rrplug_proc/src/parsing.rs @@ -1,9 +1,14 @@ use proc_macro::TokenStream; use quote::{quote, spanned::Spanned, ToTokens}; use syn::{ - self, parse::Parse, parse::ParseStream, punctuated::Punctuated, token::Comma, FnArg, Ident, - LitStr, Result as SynResult, Token, Type, __private::TokenStream2, parse_quote, - Error as SynError, + self, + parse::ParseStream, + parse::{Parse, Parser}, + punctuated::Punctuated, + token::Comma, + FnArg, Ident, LitStr, Result as SynResult, Token, Type, + __private::TokenStream2, + parse_quote, parse_str, Error as SynError, }; pub struct Arg { @@ -94,6 +99,13 @@ pub fn get_arg_type(input: &FnArg) -> Result, SynError> { } } +pub fn get_arg_ident(input: &FnArg) -> Option { + match input { + FnArg::Receiver(_) => None, + FnArg::Typed(t) => parse_str(t.pat.to_token_stream().to_string().as_str()).ok(), + } +} + fn maybe_change(ty: &Type) -> Box { match *ty { Type::BareFn(_) => Box::new(parse_quote!( diff --git a/src/lib.rs b/src/lib.rs index fdb2255..dbfe967 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ //! a git [template](https://github.com/catornot/rrplug-template) also exists but it may or not be maintained as well #![deny(unsafe_op_in_unsafe_fn)] -#![warn(missing_docs)] +// #![warn(missing_docs)] #[cfg(doctest)] use crate as rrplug; @@ -25,6 +25,7 @@ use crate as rrplug; pub mod bindings; pub mod errors; pub mod high; +pub mod interfaces; pub mod low; pub mod macros; pub mod mid;