Skip to content

Commit

Permalink
cleanup: return no results from generated shared_fn when the result i…
Browse files Browse the repository at this point in the history
…s `SharedFnResult<()>` (#58)

* cleanup: return no results from shared_fn when the result is SharedFnResult<()>

* fix: shared_fn example
  • Loading branch information
zshipko authored Jun 27, 2024
1 parent 7bd2b8e commit 6a3c50a
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{parse_macro_input, FnArg, ItemFn, ItemForeignMod};
use syn::{parse_macro_input, FnArg, GenericArgument, ItemFn, ItemForeignMod, PathArguments};

/// `plugin_fn` is used to define an Extism callable function to export
///
Expand Down Expand Up @@ -122,13 +122,13 @@ pub fn plugin_fn(
/// `extern "C" fn` should be used instead.
///
/// All arguments should implement `extism_pdk::ToBytes` and the return value should implement
/// `extism_pdk::FromBytes`
/// `extism_pdk::FromBytes`, if `()` or `SharedFnResult<()>` then no value will be returned.
/// ## Example
///
/// ```rust
/// use extism_pdk::{FnResult, shared_fn};
/// use extism_pdk::{SharedFnResult, shared_fn};
/// #[shared_fn]
/// pub fn greet2(greeting: String, name: String) -> FnResult<String> {
/// pub fn greet2(greeting: String, name: String) -> SharedFnResult<String> {
/// let s = format!("{greeting}, {name}");
/// Ok(name)
/// }
Expand Down Expand Up @@ -179,16 +179,36 @@ pub fn shared_fn(
let (no_result, raw_output) = match output {
syn::ReturnType::Default => (true, quote! {}),
syn::ReturnType::Type(_, t) => {
let mut is_unit = false;
if let syn::Type::Path(p) = t.as_ref() {
if let Some(t) = p.path.segments.last() {
if t.ident != "SharedFnResult" {
panic!("extism_pdk::shared_fn expects a function that returns extism_pdk::SharedFnResult");
}
match &t.arguments {
PathArguments::AngleBracketed(args) => {
if args.args.len() == 1 {
match &args.args[0] {
GenericArgument::Type(syn::Type::Tuple(t)) => {
if t.elems.is_empty() {
is_unit = true;
}
}
_ => (),
}
}
}
_ => (),
}
} else {
panic!("extism_pdk::shared_fn expects a function that returns extism_pdk::SharedFnResult");
}
};
(false, quote! {-> u64 })
if is_unit {
(true, quote! {})
} else {
(false, quote! {-> u64 })
}
}
};

Expand Down

0 comments on commit 6a3c50a

Please sign in to comment.