New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a name
optional argument to #[export]
#734
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,7 @@ pub(crate) struct ExportMethod { | |
pub(crate) struct ExportArgs { | ||
pub(crate) optional_args: Option<usize>, | ||
pub(crate) rpc_mode: RpcMode, | ||
pub(crate) name_override: Option<String>, | ||
} | ||
|
||
pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 { | ||
|
@@ -82,7 +83,10 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 { | |
let sig_span = sig.ident.span(); | ||
|
||
let name = sig.ident; | ||
let name_string = name.to_string(); | ||
let name_string = match args.name_override { | ||
Some(name_override) => name_override, | ||
None => name.to_string(), | ||
}; | ||
let ret_span = sig.output.span(); | ||
let ret_ty = match sig.output { | ||
syn::ReturnType::Default => quote_spanned!(ret_span => ()), | ||
|
@@ -181,6 +185,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) { | |
ImplItem::Method(mut method) => { | ||
let mut export_args = None; | ||
let mut rpc = None; | ||
let mut name_override = None; | ||
|
||
let mut errors = vec![]; | ||
|
||
|
@@ -253,8 +258,9 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) { | |
}; | ||
let path = last.ident.to_string(); | ||
|
||
// Match rpc mode | ||
// Match optional export arguments | ||
match path.as_str() { | ||
// rpc mode | ||
"rpc" => { | ||
let value = if let syn::Lit::Str(lit_str) = lit { | ||
lit_str.value() | ||
|
@@ -281,17 +287,50 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) { | |
)); | ||
return false; | ||
} | ||
} | ||
// name override | ||
"name" => { | ||
let value = if let syn::Lit::Str(lit_str) = lit { | ||
lit_str.value() | ||
} else { | ||
errors.push(syn::Error::new( | ||
last.span(), | ||
"unexpected type for name value, expected Str", | ||
)); | ||
return false; | ||
}; | ||
|
||
// NOTE: We take advantage of rust identifiers following | ||
// the same syntax rules as Godot method identifiers. See: | ||
// https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html#identifiers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it's really required that a method name is a valid identifier. We know for sure that properties can have non-identifier names: the property name of the controller of an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've just checked and indeed exported methods don't need to be valid identifiers, so I've lifted the restriction and now any string can be an exported method. |
||
match syn::parse_str::<syn::Ident>(value.as_ref()) { | ||
Ok(_) => { | ||
if name_override.replace(value).is_some() { | ||
errors.push(syn::Error::new( | ||
last.span(), | ||
"name was set more than once", | ||
)); | ||
return false; | ||
} | ||
} | ||
Err(_) => { | ||
errors.push(syn::Error::new( | ||
last.span(), | ||
"name value must be a valid identifier", | ||
)); | ||
return false; | ||
} | ||
} | ||
} | ||
_ => { | ||
let msg = | ||
format!("unknown option for export: `{}`", path); | ||
errors.push(syn::Error::new(last.span(), msg)); | ||
return false; | ||
} | ||
_ => (), | ||
} | ||
|
||
let msg = format!("unknown option for export: `{}`", path); | ||
errors.push(syn::Error::new(last.span(), msg)); | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
|
@@ -340,6 +379,7 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) { | |
|
||
export_args.optional_args = optional_args; | ||
export_args.rpc_mode = rpc.unwrap_or(RpcMode::Disabled); | ||
export_args.name_override = name_override; | ||
|
||
methods_to_export.push(ExportMethod { | ||
sig: method.sig.clone(), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be written more concisely as
args.name_override.unwrap_or_else(|| name.to_string())
, I believe?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better, thanks!