Skip to content

Commit

Permalink
Convert panics to syn errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Vurv78 committed Dec 29, 2024
1 parent d9967fb commit 3c77ea1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 21 deletions.
2 changes: 1 addition & 1 deletion rglua-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rglua-macros"
description = "Procedural macros to be used with rglua"
version = "0.2.0"
version = "0.3.0"
authors = ["Vurv <vurvdevelops@gmail.com>"]
keywords = ["glua", "garrysmod", "lua", "gmod"]
categories = ["api-bindings", "external-ffi-bindings", "development-tools::ffi", "game-development", "accessibility"]
Expand Down
40 changes: 22 additions & 18 deletions rglua-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
use proc_macro::TokenStream;
use quote::{quote, ToTokens};

use syn::{parse_macro_input, parse_quote, FnArg, ItemFn, ReturnType, Type};
use syn::{parse_macro_input, parse_quote, spanned::Spanned, FnArg, ItemFn, ReturnType, Type};

fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
let mut returns_result: Option<&Box<Type>> = None;

let mut ast = parse_macro_input!(item as ItemFn);

assert!(ast.sig.asyncness.is_none(), "Cannot be asynchronous");
assert!(ast.sig.constness.is_none(), "Cannot be const");
assert!(
ast.sig.inputs.len() == 1,
"Must have one parameter, being the Lua state (rglua::lua::LuaState)"
);
if ast.sig.asyncness.is_some() {
return syn::Error::new(ast.sig.span(), "Cannot be async").into_compile_error().into();
}

if ast.sig.constness.is_some() {
return syn::Error::new(ast.sig.span(), "Cannot be const").into_compile_error().into();
}

if ast.sig.inputs.len() != 1 {
return syn::Error::new(ast.sig.span(), "Must have one parameter, being the Lua state (rglua::lua::LuaState)").into_compile_error().into();
}

if let ReturnType::Type(_, ty) = &ast.sig.output {
let mut ret = ty.to_token_stream().to_string();
if ret.starts_with("Result < i32") | ret.starts_with("std :: result :: Result < i32") {
ret.retain(|c| !c.is_whitespace());
returns_result = Some(ty);
} else {
assert!(
ret.as_str() == "i32",
"Exported function must return i32 or Result<i32, E>"
);
if ret.as_str() != "i32" {
return syn::Error::new(ast.sig.output.span(), "Exported function must return i32 or Result<i32, E>").into_compile_error().into();
}
}
} else {
panic!("Exported function must return i32 or Result<i32, E>");
return syn::Error::new(ast.sig.output.span(), "Exported function must return i32 or Result<i32, E>").into_compile_error().into();
}

let lua_shared_param;
let lua_shared_ty;
// Make sure parameter is a LuaState
match ast.sig.inputs.first().unwrap() {
FnArg::Receiver(_) => panic!("Parameter cannot be self"),
FnArg::Receiver(_) => return syn::Error::new(ast.sig.inputs.span(), "Parameter cannot be self").into_compile_error().into(),
FnArg::Typed(arg) => {
// In the future this could check if it is *c_void as well.
match arg.ty.to_token_stream().to_string().as_str() {
"LuaState" | "rglua :: lua :: LuaState" => (),
a => panic!("Parameter must be rglua::lua::LuaState. Got {}", a),
a => return syn::Error::new(arg.ty.span(), format!("Parameter must be rglua::lua::LuaState. Got {a}")).to_compile_error().into(),
}

lua_shared_ty = &arg.ty;
Expand All @@ -49,9 +53,9 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
lua_shared_param = &i.ident;
}
syn::Pat::Wild(_) => {
panic!("Parameter must be named. Try _foo");
return syn::Error::new(arg.pat.span(), "Parameter must be named. Try _foo").to_compile_error().into();
}
_ => panic!("Parameter must be in ``ident: ty`` format"),
_ => return syn::Error::new(arg.pat.span(), "Parameter must be in 'ident: ty' format").to_compile_error().into(),
}
}
}
Expand All @@ -60,7 +64,7 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
if let Some(abi) = &ast.sig.abi {
match abi.name.as_ref().unwrap().value().as_str() {
"C" | "C-unwind" => (),
_ => panic!("Only C (or C-unwind) ABI is supported"),
_ => return syn::Error::new(abi.span(), "Only C or C-unwind are supported").to_compile_error().into(),
}
} else {
ast.sig.abi = Some(parse_quote!(extern "C"))
Expand Down Expand Up @@ -115,7 +119,7 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
for attr in &ast.attrs {
if let Some(id) = attr.path.get_ident() {
if id == "no_mangle" {
panic!("Using no_mangle is unnecessary on exported functions");
return syn::Error::new(id.span(), "Using no_mangle is unnecessary on exported functions").into_compile_error().into();
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions rglua/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rglua"
description = "Toolkit for garrysmod development with the source sdk and luajit api"
version = "3.0.0-beta2"
version = "3.0.0"
authors = ["Vurv <vurvdevelops@gmail.com>"]
keywords = ["glua", "garrysmod", "lua", "gmod"]
categories = ["api-bindings", "external-ffi-bindings", "development-tools::ffi", "game-development", "accessibility"]
Expand All @@ -17,7 +17,7 @@ libloading = "0.7.2"
once_cell = "1.8.0"
thiserror = "1.0.30"

rglua-macros = { version = "0.2.0", path = "../rglua-macros" }
rglua-macros = { version = "0.3.0", path = "../rglua-macros" }

viable = { version = "0.2", optional = true }

Expand Down

0 comments on commit 3c77ea1

Please # to comment.