mirror of
https://git.proxmox.com/git/perlmod
synced 2025-10-04 16:50:06 +00:00
add support for raw parameters
#[export] fn foo(#[raw] this: Value) -> Result<(), Error>; Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
29e61fa65e
commit
0cdb12e277
@ -14,19 +14,18 @@ pub struct XSub {
|
|||||||
|
|
||||||
pub fn handle_function(
|
pub fn handle_function(
|
||||||
attr: FunctionAttrs,
|
attr: FunctionAttrs,
|
||||||
func: syn::ItemFn,
|
mut func: syn::ItemFn,
|
||||||
mangled_package_name: Option<&str>,
|
mangled_package_name: Option<&str>,
|
||||||
) -> Result<XSub, Error> {
|
) -> Result<XSub, Error> {
|
||||||
let sig = &func.sig;
|
if !func.sig.generics.params.is_empty() {
|
||||||
if !sig.generics.params.is_empty() {
|
bail!(&func.sig.generics => "generic functions cannot be exported as xsubs");
|
||||||
bail!(&sig.generics => "generic functions cannot be exported as xsubs");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.asyncness.is_some() {
|
if func.sig.asyncness.is_some() {
|
||||||
bail!(&sig.asyncness => "async fns cannot be exported as xsubs");
|
bail!(&func.sig.asyncness => "async fns cannot be exported as xsubs");
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = &sig.ident;
|
let name = func.sig.ident.clone();
|
||||||
let xs_name = attr.xs_name.unwrap_or_else(|| match mangled_package_name {
|
let xs_name = attr.xs_name.unwrap_or_else(|| match mangled_package_name {
|
||||||
None => Ident::new(&format!("xs_{}", name), name.span()),
|
None => Ident::new(&format!("xs_{}", name), name.span()),
|
||||||
Some(prefix) => Ident::new(&format!("xs_{}_{}", prefix, name), name.span()),
|
Some(prefix) => Ident::new(&format!("xs_{}_{}", prefix, name), name.span()),
|
||||||
@ -36,10 +35,22 @@ pub fn handle_function(
|
|||||||
let mut extract_arguments = TokenStream::new();
|
let mut extract_arguments = TokenStream::new();
|
||||||
let mut deserialized_arguments = TokenStream::new();
|
let mut deserialized_arguments = TokenStream::new();
|
||||||
let mut passed_arguments = TokenStream::new();
|
let mut passed_arguments = TokenStream::new();
|
||||||
for arg in &sig.inputs {
|
for arg in &mut func.sig.inputs {
|
||||||
|
let mut raw_arg = false;
|
||||||
|
|
||||||
let pat_ty = match arg {
|
let pat_ty = match arg {
|
||||||
syn::FnArg::Receiver(_) => bail!(arg => "cannot export self-taking methods as xsubs"),
|
syn::FnArg::Receiver(_) => bail!(arg => "cannot export self-taking methods as xsubs"),
|
||||||
syn::FnArg::Typed(pt) => pt,
|
syn::FnArg::Typed(ref mut pt) => {
|
||||||
|
pt.attrs.retain(|attr| {
|
||||||
|
if attr.path.is_ident("raw") {
|
||||||
|
raw_arg = true;
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
&*pt
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let arg_name = match &*pat_ty.pat {
|
let arg_name = match &*pat_ty.pat {
|
||||||
@ -74,16 +85,22 @@ pub fn handle_function(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
deserialized_arguments.extend(quote! {
|
if raw_arg {
|
||||||
let #deserialized_name: #arg_type = match ::perlmod::from_value(#extracted_name) {
|
deserialized_arguments.extend(quote! {
|
||||||
Ok(data) => data,
|
let #deserialized_name = #extracted_name;
|
||||||
Err(err) => {
|
});
|
||||||
return Err(::perlmod::Value::new_string(&err.to_string())
|
} else {
|
||||||
.into_mortal()
|
deserialized_arguments.extend(quote! {
|
||||||
.into_raw());
|
let #deserialized_name: #arg_type = match ::perlmod::from_value(#extracted_name) {
|
||||||
}
|
Ok(data) => data,
|
||||||
};
|
Err(err) => {
|
||||||
});
|
return Err(::perlmod::Value::new_string(&err.to_string())
|
||||||
|
.into_mortal()
|
||||||
|
.into_raw());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if passed_arguments.is_empty() {
|
if passed_arguments.is_empty() {
|
||||||
passed_arguments.extend(quote! { #deserialized_name });
|
passed_arguments.extend(quote! { #deserialized_name });
|
||||||
@ -96,7 +113,7 @@ pub fn handle_function(
|
|||||||
&format!(
|
&format!(
|
||||||
"too many parameters for function '{}', (expected {})",
|
"too many parameters for function '{}', (expected {})",
|
||||||
name,
|
name,
|
||||||
sig.inputs.len()
|
func.sig.inputs.len()
|
||||||
),
|
),
|
||||||
Span::call_site(),
|
Span::call_site(),
|
||||||
);
|
);
|
||||||
|
@ -12,4 +12,11 @@ mod export {
|
|||||||
Ok(hash)
|
Ok(hash)
|
||||||
//Ok(this.bless("RSPM::Bless")?)
|
//Ok(this.bless("RSPM::Bless")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[export]
|
||||||
|
fn something(#[raw] value: Value) -> Result<(), Error> {
|
||||||
|
println!("Called something!");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user