repo clean up

This commit is contained in:
Timur Gordon
2025-08-02 11:19:25 +02:00
parent 1074e1ba19
commit 0f3ea0fe2f
19 changed files with 4 additions and 1064 deletions

290
_archive/rhai_client_macros/Cargo.lock generated Normal file
View File

@@ -0,0 +1,290 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"const-random",
"getrandom 0.3.3",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom 0.2.16",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "crunchy"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
dependencies = [
"portable-atomic",
]
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rhai"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce4d759a4729a655ddfdbb3ff6e77fb9eadd902dae12319455557796e435d2a6"
dependencies = [
"ahash",
"bitflags",
"instant",
"num-traits",
"once_cell",
"rhai_codegen",
"smallvec",
"smartstring",
"thin-vec",
]
[[package]]
name = "rhai_client_macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"rhai",
"syn",
]
[[package]]
name = "rhai_codegen"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smallvec"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]]
name = "smartstring"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
dependencies = [
"autocfg",
"static_assertions",
"version_check",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thin-vec"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@@ -0,0 +1,14 @@
[package]
name = "rhai_client_macros"
version = "0.1.0"
edition = "2021"
description = "Procedural macros for generating Rhai client functions from Rust functions"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full", "extra-traits"] }
rhai = "1.21.0"

View File

@@ -0,0 +1,360 @@
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, parse_quote, FnArg, ItemFn, Pat, PatType, ReturnType};
/// Procedural macro that generates a Rhai client function for a Rust function.
///
/// When applied to a Rust function, it generates a corresponding function with a '_rhai_client' suffix
/// that calls the original function through the Rhai engine.
///
/// # Example
///
/// ```rust
/// #[rhai]
/// fn hello(name: String) -> String {
/// format!("Hello, {}!", name)
/// }
/// ```
///
/// This will generate:
///
/// ```rust
/// fn hello_rhai_client(engine: &rhai::Engine, name: String) -> String {
/// let script = format!("hello(\"{}\")", name.replace("\"", "\\\""));
/// engine.eval::<String>(&script).unwrap_or_else(|err| {
/// eprintln!("Rhai script error: {}", err);
/// String::new()
/// })
/// }
/// ```
///
/// Note: The macro handles type conversions between Rust and Rhai types,
/// particularly for integer types (Rhai uses i64 internally).
#[proc_macro_attribute]
pub fn rhai(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the input function
let input_fn = parse_macro_input!(item as ItemFn);
let fn_name = &input_fn.sig.ident;
let fn_name_str = fn_name.to_string();
// Create the client function name (original + _rhai_client)
let client_fn_name = format_ident!("{}_rhai_client", fn_name);
// Extract function parameters
let mut param_names = Vec::new();
let mut param_types = Vec::new();
let mut param_declarations = Vec::new();
for arg in &input_fn.sig.inputs {
match arg {
FnArg::Typed(PatType { pat, ty, .. }) => {
if let Pat::Ident(pat_ident) = &**pat {
let param_name = &pat_ident.ident;
param_names.push(param_name.clone());
param_types.push(ty.clone());
param_declarations.push(quote! { #param_name: #ty });
}
}
_ => {
// Skip self parameters
continue;
}
}
}
// Determine return type
let return_type = match &input_fn.sig.output {
ReturnType::Default => parse_quote!(()),
ReturnType::Type(_, ty) => ty.clone(),
};
// Generate parameter formatting for the Rhai script
let param_format_strings = param_names
.iter()
.zip(param_types.iter())
.map(|(name, ty)| {
let type_str = quote! { #ty }.to_string();
// Handle different parameter types
if type_str.contains("String") {
quote! {
format!("\"{}\"" , #name.replace("\"", "\\\""))
}
} else if type_str.contains("bool") {
quote! {
format!("{}", #name)
}
} else if type_str.contains("i32") || type_str.contains("u32") {
// Convert smaller integer types to i64 for Rhai
quote! {
format!("{}", #name as i64)
}
} else if type_str.contains("i64")
|| type_str.contains("u64")
|| type_str.contains("f32")
|| type_str.contains("f64")
{
// Other numeric types
quote! {
format!("{}", #name)
}
} else {
// For complex types, just pass the variable name
// The Rhai engine will handle the conversion
quote! {
#name.to_string()
}
}
});
// Determine if the return type needs conversion
let return_type_str = quote! { #return_type }.to_string();
// Generate the client function with appropriate type conversions
let client_fn = if return_type_str.contains("i32") || return_type_str.contains("u32") {
// For integer return types that need conversion
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_strings),*].join(", ")
);
match engine.eval::<i64>(&script) {
Ok(result) => result as #return_type,
Err(err) => {
eprintln!("Rhai script error: {}", err);
0 as #return_type // Use 0 as default for numeric types
}
}
}
}
} else if return_type_str.contains("String") {
// For String return type
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_strings),*].join(", ")
);
match engine.eval::<#return_type>(&script) {
Ok(result) => result,
Err(err) => {
eprintln!("Rhai script error: {}", err);
String::new() // Empty string as default
}
}
}
}
} else if return_type_str.contains("bool") {
// For boolean return type
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_strings),*].join(", ")
);
match engine.eval::<#return_type>(&script) {
Ok(result) => result,
Err(err) => {
eprintln!("Rhai script error: {}", err);
false // False as default
}
}
}
}
} else {
// For complex types or other types
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_strings),*].join(", ")
);
match engine.eval::<#return_type>(&script) {
Ok(result) => result,
Err(err) => {
eprintln!("Rhai script error: {}", err);
panic!("Failed to evaluate Rhai script: {}", err) // Panic for complex types
}
}
}
}
};
// Combine the original function and the generated client function
let output = quote! {
#input_fn
#client_fn
};
output.into()
}
/// A more advanced version of the rhai macro that handles different parameter types better.
///
/// This version properly escapes strings and handles different parameter types more accurately.
/// It's recommended to use this version for more complex functions.
#[proc_macro_attribute]
pub fn rhai_advanced(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the input function
let input_fn = parse_macro_input!(item as ItemFn);
let fn_name = &input_fn.sig.ident;
let fn_name_str = fn_name.to_string();
// Create the client function name (original + _rhai_client)
let client_fn_name = format_ident!("{}_rhai_client", fn_name);
// Extract function parameters
let mut param_names = Vec::new();
let mut param_types = Vec::new();
let mut param_declarations = Vec::new();
for arg in &input_fn.sig.inputs {
match arg {
FnArg::Typed(PatType { pat, ty, .. }) => {
if let Pat::Ident(pat_ident) = &**pat {
let param_name = &pat_ident.ident;
param_names.push(param_name.clone());
param_types.push(ty.clone());
param_declarations.push(quote! { #param_name: #ty });
}
}
_ => {
// Skip self parameters
continue;
}
}
}
// Determine return type
let return_type = match &input_fn.sig.output {
ReturnType::Default => parse_quote!(()),
ReturnType::Type(_, ty) => ty.clone(),
};
// Generate parameter formatting for the Rhai script
let param_format_expressions = param_names
.iter()
.zip(param_types.iter())
.map(|(name, ty)| {
let type_str = quote! { #ty }.to_string();
// Handle different parameter types
if type_str.contains("String") {
quote! {
format!("\"{}\"", #name.replace("\"", "\\\""))
}
} else if type_str.contains("bool") {
quote! {
format!("{}", #name)
}
} else if type_str.contains("i32") || type_str.contains("u32") {
// Convert smaller integer types to i64 for Rhai
quote! {
format!("{}", #name as i64)
}
} else if type_str.contains("i") || type_str.contains("u") || type_str.contains("f") {
// Other numeric types
quote! {
format!("{}", #name)
}
} else {
// Default for other types
quote! {
format!("{:?}", #name)
}
}
})
.collect::<Vec<_>>();
// Determine if the return type needs conversion
let return_type_str = quote! { #return_type }.to_string();
let needs_return_conversion =
return_type_str.contains("i32") || return_type_str.contains("u32");
// Generate the client function with appropriate type conversions
let client_fn = if needs_return_conversion {
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_expressions),*].join(", ")
);
match engine.eval::<i64>(&script) {
Ok(result) => result as #return_type,
Err(err) => {
eprintln!("Rhai script error: {}", err);
#return_type::default()
}
}
}
}
} else {
quote! {
fn #client_fn_name(engine: &rhai::Engine, #(#param_declarations),*) -> #return_type {
let script = format!(
"{}({})",
#fn_name_str,
&[#(#param_format_expressions),*].join(", ")
);
match engine.eval::<#return_type>(&script) {
Ok(result) => result,
Err(err) => {
eprintln!("Rhai script error: {}", err);
#return_type::default()
}
}
}
}
};
// Combine the original function and the generated client function
let output = quote! {
#input_fn
#client_fn
};
output.into()
}
/// Macro that generates a module with Rhai client functions for all functions in scope.
///
/// This macro should be used at the module level to generate Rhai client functions for all
/// functions marked with the #[rhai] attribute.
#[proc_macro]
pub fn generate_rhai_module(_item: TokenStream) -> TokenStream {
// This would be a more complex implementation that would need to
// scan the module for functions marked with #[rhai] and generate
// client functions for all of them.
//
// For simplicity, we'll just return a placeholder implementation
let output = quote! {
/// Register all functions marked with #[rhai] in this module with the Rhai engine.
///
/// This function handles type conversions between Rust and Rhai types automatically.
/// For example, it converts between Rust's i32 and Rhai's i64 types.
pub fn register_rhai_functions(engine: &mut rhai::Engine) {
// This would be generated based on the functions in the module
println!("Registering Rhai functions...");
// In a real implementation, this would iterate through all functions
// marked with #[rhai] and register them with the engine.
}
};
output.into()
}