Add get/set/index_get/index_set parameters to rhai_fn.

This commit is contained in:
Stephen Chung 2020-08-17 00:13:52 +08:00
parent e75d91e9bf
commit 810514dd31
5 changed files with 53 additions and 15 deletions

View File

@ -13,9 +13,15 @@ use std::collections::HashMap;
use quote::{quote, quote_spanned}; use quote::{quote, quote_spanned};
use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned}; use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
use super::rhai_module::get_register_name;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub(crate) struct ExportedFnParams { pub(crate) struct ExportedFnParams {
pub name: Option<String>, pub name: Option<String>,
pub get: Option<String>,
pub set: Option<String>,
pub index_get: bool,
pub index_set: bool,
pub return_raw: bool, pub return_raw: bool,
pub skip: bool, pub skip: bool,
} }
@ -76,14 +82,24 @@ impl Parse for ExportedFnParams {
} }
let mut name = None; let mut name = None;
let mut get = None;
let mut set = None;
let mut index_get = false;
let mut index_set = false;
let mut return_raw = false; let mut return_raw = false;
let mut skip = false; let mut skip = false;
for (ident, value) in attrs.drain() { for (ident, value) in attrs.drain() {
match (ident.to_string().as_ref(), value) { match (ident.to_string().as_ref(), value) {
("name", Some(s)) => name = Some(s.value()), ("name", Some(s)) => name = Some(s.value()),
("name", None) => return Err(syn::Error::new(ident.span(), "requires value")), ("get", Some(s)) => get = Some(s.value()),
("set", Some(s)) => set = Some(s.value()),
("get", None) | ("set", None) | ("name", None) => {
return Err(syn::Error::new(ident.span(), "requires value"))
}
("index_get", None) => index_get = true,
("index_set", None) => index_get = true,
("return_raw", None) => return_raw = true, ("return_raw", None) => return_raw = true,
("return_raw", Some(s)) => { ("index_get", Some(s)) | ("index_set", Some(s)) | ("return_raw", Some(s)) => {
return Err(syn::Error::new(s.span(), "extraneous value")) return Err(syn::Error::new(s.span(), "extraneous value"))
} }
("skip", None) => skip = true, ("skip", None) => skip = true,
@ -99,6 +115,10 @@ impl Parse for ExportedFnParams {
Ok(ExportedFnParams { Ok(ExportedFnParams {
name, name,
get,
set,
index_get,
index_set,
return_raw, return_raw,
skip, skip,
..Default::default() ..Default::default()
@ -353,11 +373,7 @@ impl ExportedFn {
pub fn generate_impl(&self, on_type_name: &str) -> proc_macro2::TokenStream { pub fn generate_impl(&self, on_type_name: &str) -> proc_macro2::TokenStream {
let sig_name = self.name().clone(); let sig_name = self.name().clone();
let name = if let Some(ref name) = self.params.name { let name = get_register_name(self);
name.clone()
} else {
self.name().to_string()
};
let arg_count = self.arg_count(); let arg_count = self.arg_count();
let is_method_call = self.mutable_receiver(); let is_method_call = self.mutable_receiver();

View File

@ -4,6 +4,32 @@ use crate::function::ExportedFn;
pub(crate) type ExportedConst = (String, syn::Expr); pub(crate) type ExportedConst = (String, syn::Expr);
pub(crate) fn get_register_name(function: &ExportedFn) -> String {
pub const FN_IDX_GET: &str = "index$get$";
pub const FN_IDX_SET: &str = "index$set$";
pub fn make_getter(id: &str) -> String {
format!("get${}", id)
}
pub fn make_setter(id: &str) -> String {
format!("set${}", id)
}
if let Some(ref name) = function.params.name {
name.clone()
} else if let Some(ref name) = function.params.get {
make_getter(name).clone()
} else if let Some(ref name) = function.params.set {
make_setter(name).clone()
} else if function.params.index_get {
FN_IDX_GET.to_string()
} else if function.params.index_set {
FN_IDX_SET.to_string()
} else {
function.name().to_string()
}
}
pub(crate) fn generate_body( pub(crate) fn generate_body(
fns: &Vec<ExportedFn>, fns: &Vec<ExportedFn>,
consts: &Vec<ExportedConst>, consts: &Vec<ExportedConst>,
@ -29,11 +55,7 @@ pub(crate) fn generate_body(
&format!("{}_token", function.name().to_string()), &format!("{}_token", function.name().to_string()),
function.name().span(), function.name().span(),
); );
let reg_name = if let Some(ref name) = function.params.name { let reg_name = get_register_name(function);
name.clone()
} else {
function.name().to_string()
};
let fn_literal = syn::LitStr::new(&reg_name, proc_macro2::Span::call_site()); let fn_literal = syn::LitStr::new(&reg_name, proc_macro2::Span::call_site());
let fn_input_types: Vec<syn::Expr> = function let fn_input_types: Vec<syn::Expr> = function
.arg_list() .arg_list()

View File

@ -140,7 +140,7 @@ mod array_functions {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[export_module] #[export_module]
mod object_functions { mod object_functions {
#[rhai_fn(name = "get$len")] #[rhai_fn(get = "len")]
pub fn len(list: &mut Array) -> INT { pub fn len(list: &mut Array) -> INT {
array_functions::len(list) array_functions::len(list)
} }

View File

@ -24,7 +24,7 @@ mod map_functions {
pub fn len(map: &mut Map) -> INT { pub fn len(map: &mut Map) -> INT {
map.len() as INT map.len() as INT
} }
#[rhai_fn(name = "get$len")] #[rhai_fn(get = "len")]
pub fn len_prop(map: &mut Map) -> INT { pub fn len_prop(map: &mut Map) -> INT {
len(map) len(map)
} }

View File

@ -342,7 +342,7 @@ mod index_functions {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[export_module] #[export_module]
mod object_functions { mod object_functions {
#[rhai_fn(name = "get$len")] #[rhai_fn(get = "len")]
pub fn len(s: &mut ImmutableString) -> INT { pub fn len(s: &mut ImmutableString) -> INT {
string_functions::len(s) string_functions::len(s)
} }