Simplify macro system and update doc comments.

This commit is contained in:
Stephen Chung
2020-09-30 22:55:40 +08:00
parent e526b53b42
commit a04ed02b54
10 changed files with 174 additions and 196 deletions

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2018"
authors = ["jhwgh1968"]
description = "Proceducral macro support package for Rhai, a scripting language for Rust"
homepage = "https://github.com/jonathandturner/rhai"
homepage = "https://schungx.github.io/rhai/plugins/index.html"
repository = "https://github.com/jonathandturner/rhai"
license = "MIT OR Apache-2.0"

View File

@@ -628,7 +628,7 @@ impl ExportedFn {
arg_type.span()=> &mut args[0usize].write_lock::<#arg_type>().unwrap());
unpack_stmts.push(
syn::parse2::<syn::Stmt>(quote! {
let #var: &mut _ = #downcast_span;
let #var = #downcast_span;
})
.unwrap(),
);
@@ -757,7 +757,7 @@ impl ExportedFn {
}
fn is_method_call(&self) -> bool { #is_method_call }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(#type_name()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![#(#input_type_exprs),*].into_boxed_slice()

View File

@@ -1,17 +1,14 @@
//! This crate contains procedural macros to make creating Rhai plugin-modules much easier.
//!
//! This crate contains procedural macros to make creating Rhai modules much easier.
//!
//! # Exporting a Macro to Rhai
//! # Export an Entire Rust Module to a Rhai Module
//!
//! ```
//! use rhai::{EvalAltResult, FLOAT};
//! use rhai::plugin::*;
//! use rhai::module_resolvers::*;
//!
//! #[rhai::export_module]
//! pub mod advanced_math {
//! use rhai::FLOAT;
//!
//! #[export_module]
//! mod advanced_math {
//! pub const MYSTIC_NUMBER: FLOAT = 42.0 as FLOAT;
//!
//! pub fn euclidean_distance(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
@@ -35,15 +32,15 @@
//! }
//! ```
//!
//! # Exporting a Function to a Rhai Module
//! # Export a Rust Function to a Rhai Module
//!
//! ```
//! use rhai::{EvalAltResult, FLOAT, Module, RegisterFn};
//! use rhai::plugin::*;
//! use rhai::module_resolvers::*;
//!
//! #[rhai::export_fn]
//! pub fn distance_function(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
//! #[export_fn]
//! fn distance_function(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
//! ((y2 - y1).abs().powf(2.0) + (x2 -x1).abs().powf(2.0)).sqrt()
//! }
//!
@@ -105,6 +102,18 @@ mod rhai_module;
#[cfg(test)]
mod test;
/// Attribute, when put on a Rust function, turns it into a _plugin function_.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_fn]
/// fn my_plugin_function(...) {
/// ...
/// }
/// ```
#[proc_macro_attribute]
pub fn export_fn(
args: proc_macro::TokenStream,
@@ -125,6 +134,18 @@ pub fn export_fn(
proc_macro::TokenStream::from(output)
}
/// Attribute, when put on a Rust module, turns it into a _plugin module_.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_module]
/// mod my_plugin_module {
/// ...
/// }
/// ```
#[proc_macro_attribute]
pub fn export_module(
args: proc_macro::TokenStream,
@@ -143,6 +164,20 @@ pub fn export_module(
proc_macro::TokenStream::from(tokens)
}
/// Macro to generate a Rhai `Module` from a _plugin module_.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_module]
/// mod my_plugin_module {
/// ...
/// }
///
/// let module = exported_module!(my_plugin_module);
/// ```
#[proc_macro]
pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::TokenStream {
let module_path = parse_macro_input!(module_path as syn::Path);
@@ -152,6 +187,34 @@ pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::Toke
proc_macro::TokenStream::from(tokens)
}
/// Macro to combine a _plugin module_ into an existing module.
///
/// Functions and variables in the plugin module overrides any existing similarly-named
/// functions and variables in the target module.
///
/// This call is intended to be used within the `def_package!` macro to define a custom
/// package based on a plugin module.
///
/// All sub-modules, if any, in the plugin module are _flattened_ and their functions/variables
/// registered at the top level because packages require so.
///
/// The text string name in the second parameter can be anything and is reserved for future use;
/// it is recommended to be an ID string that uniquely identifies the plugin module.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_module]
/// mod my_plugin_module {
/// ...
/// }
///
/// let mut module = Module::new();
///
/// combine_with_exported_module!(&mut module, "my_plugin_module_ID", my_plugin_module);
/// ```
#[proc_macro]
pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (module_expr, _export_name, module_path) = match crate::register::parse_register_macro(args)
@@ -165,6 +228,22 @@ pub fn combine_with_exported_module(args: proc_macro::TokenStream) -> proc_macro
proc_macro::TokenStream::from(tokens)
}
/// Macro to register a _plugin function_ into an `Engine`.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_fn]
/// fn my_plugin_function(...) {
/// ...
/// }
///
/// let mut engine = Engine::new();
///
/// register_exported_fn!(engine, "calc", my_plugin_function);
/// ```
#[proc_macro]
pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (engine_expr, export_name, rust_modpath) = match crate::register::parse_register_macro(args)
@@ -179,6 +258,22 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS
proc_macro::TokenStream::from(tokens)
}
/// Macro to register a _plugin function_ into a Rhai `Module`.
///
/// # Usage
///
/// ```no_run
/// use rhai::plugin::*;
///
/// #[export_fn]
/// fn my_plugin_function(...) {
/// ...
/// }
///
/// let mut module = Module::new();
///
/// set_exported_fn!(module, "calc", my_plugin_function);
/// ```
#[proc_macro]
pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
let (module_expr, export_name, rust_modpath) = match crate::register::parse_register_macro(args)

View File

@@ -283,7 +283,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![].into_boxed_slice()
@@ -328,7 +328,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![TypeId::of::<usize>()].into_boxed_slice()
@@ -369,7 +369,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(MyType()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![TypeId::of::<usize>()].into_boxed_slice()
@@ -404,7 +404,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![TypeId::of::<usize>(),
@@ -446,12 +446,12 @@ mod generate_tests {
debug_assert_eq!(args.len(), 2usize,
"wrong arg count: {} != {}", args.len(), 2usize);
let arg1 = mem::take(args[1usize]).cast::<usize>();
let arg0: &mut _ = &mut args[0usize].write_lock::<usize>().unwrap();
let arg0 = &mut args[0usize].write_lock::<usize>().unwrap();
Ok(Dynamic::from(increment(arg0, arg1)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![TypeId::of::<usize>(),
@@ -498,7 +498,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[TypeId]> {
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()

View File

@@ -311,7 +311,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(get_mystic_number_token())
}
@@ -374,7 +374,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_one_to_token())
}
@@ -451,7 +451,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_one_to_token())
}
@@ -480,7 +480,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_n_to_token())
}
@@ -546,7 +546,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_together_token())
}
@@ -619,7 +619,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_together_token())
}
@@ -859,7 +859,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(get_mystic_number_token())
}
@@ -953,7 +953,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(print_out_to_token())
}
@@ -1017,7 +1017,7 @@ mod generate_tests {
}
fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(print_out_to_token())
}
@@ -1076,12 +1076,12 @@ mod generate_tests {
) -> Result<Dynamic, Box<EvalAltResult>> {
debug_assert_eq!(args.len(), 1usize,
"wrong arg count: {} != {}", args.len(), 1usize);
let arg0: &mut _ = &mut args[0usize].write_lock::<FLOAT>().unwrap();
let arg0 = &mut args[0usize].write_lock::<FLOAT>().unwrap();
Ok(Dynamic::from(increment(arg0)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(increment_token())
}
@@ -1143,12 +1143,12 @@ mod generate_tests {
) -> Result<Dynamic, Box<EvalAltResult>> {
debug_assert_eq!(args.len(), 1usize,
"wrong arg count: {} != {}", args.len(), 1usize);
let arg0: &mut _ = &mut args[0usize].write_lock::<FLOAT>().unwrap();
let arg0 = &mut args[0usize].write_lock::<FLOAT>().unwrap();
Ok(Dynamic::from(increment(arg0)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(increment_token())
}
@@ -1230,12 +1230,12 @@ mod generate_tests {
) -> Result<Dynamic, Box<EvalAltResult>> {
debug_assert_eq!(args.len(), 1usize,
"wrong arg count: {} != {}", args.len(), 1usize);
let arg0: &mut _ = &mut args[0usize].write_lock::<FLOAT>().unwrap();
let arg0 = &mut args[0usize].write_lock::<FLOAT>().unwrap();
Ok(Dynamic::from(increment(arg0)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(increment_token())
}
@@ -1315,12 +1315,12 @@ mod generate_tests {
) -> Result<Dynamic, Box<EvalAltResult>> {
debug_assert_eq!(args.len(), 1usize,
"wrong arg count: {} != {}", args.len(), 1usize);
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
let arg0 = &mut args[0usize].write_lock::<u64>().unwrap();
Ok(Dynamic::from(int_foo(arg0)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(int_foo_token())
}
@@ -1381,12 +1381,12 @@ mod generate_tests {
) -> Result<Dynamic, Box<EvalAltResult>> {
debug_assert_eq!(args.len(), 1usize,
"wrong arg count: {} != {}", args.len(), 1usize);
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
let arg0 = &mut args[0usize].write_lock::<u64>().unwrap();
Ok(Dynamic::from(int_foo(arg0)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(int_foo_token())
}
@@ -1448,12 +1448,12 @@ mod generate_tests {
debug_assert_eq!(args.len(), 2usize,
"wrong arg count: {} != {}", args.len(), 2usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
let arg0 = &mut args[0usize].write_lock::<u64>().unwrap();
Ok(Dynamic::from(int_foo(arg0, arg1)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(int_foo_token())
}
@@ -1519,12 +1519,12 @@ mod generate_tests {
debug_assert_eq!(args.len(), 2usize,
"wrong arg count: {} != {}", args.len(), 2usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
let arg0 = &mut args[0usize].write_lock::<u64>().unwrap();
Ok(Dynamic::from(int_foo(arg0, arg1)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(int_foo_token())
}
@@ -1586,12 +1586,12 @@ mod generate_tests {
debug_assert_eq!(args.len(), 2usize,
"wrong arg count: {} != {}", args.len(), 2usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
let arg0 = &mut args[0usize].write_lock::<MyCollection>().unwrap();
Ok(Dynamic::from(get_by_index(arg0, arg1)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(get_by_index_token())
}
@@ -1658,12 +1658,12 @@ mod generate_tests {
debug_assert_eq!(args.len(), 2usize,
"wrong arg count: {} != {}", args.len(), 2usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
let arg0 = &mut args[0usize].write_lock::<MyCollection>().unwrap();
Ok(Dynamic::from(get_by_index(arg0, arg1)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(get_by_index_token())
}
@@ -1728,12 +1728,12 @@ mod generate_tests {
"wrong arg count: {} != {}", args.len(), 3usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg2 = mem::take(args[2usize]).cast::<FLOAT>();
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
let arg0 = &mut args[0usize].write_lock::<MyCollection>().unwrap();
Ok(Dynamic::from(set_by_index(arg0, arg1, arg2)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(set_by_index_token())
}
@@ -1804,12 +1804,12 @@ mod generate_tests {
"wrong arg count: {} != {}", args.len(), 3usize);
let arg1 = mem::take(args[1usize]).cast::<u64>();
let arg2 = mem::take(args[2usize]).cast::<FLOAT>();
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
let arg0 = &mut args[0usize].write_lock::<MyCollection>().unwrap();
Ok(Dynamic::from(set_by_index(arg0, arg1, arg2)))
}
fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false }
fn is_variadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(set_by_index_token())
}