Skip to content

Commit

Permalink
feat(wasm): rename js method
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexcited committed Dec 29, 2024
1 parent 047dd62 commit cf8d900
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
19 changes: 14 additions & 5 deletions wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ Will use the `wee_alloc` crate to set up a global allocator for the `wasm32` tar

### `api_method`

A `fetcher` parameter is automatically added to the function signature.
See the [`fetcher` module](../fetcher) for more information.

```rust
#[cfg_attr(target_arch = "wasm32", wasm::api_method)]
// the method will be called `fetchGitHub` in the generated bindings
#[cfg_attr(target_arch = "wasm32", wasm::api_method(fetchGitHub))]
pub async fn fetch_github(something: String) -> String {
"hello world".to_string()
// a `fetcher` variable is available
// if the target architecture is `wasm32`
}
```

A `fetcher` parameter is automatically added to the function signature.
See the [`fetcher` module](../fetcher) for more information.
// the method will stille be called `update` in the generated bindings
#[cfg_attr(target_arch = "wasm32", wasm::api_method)]
pub async fn update(something: String) -> String {
// a `fetcher` variable is available
// if the target architecture is `wasm32`
}
```
60 changes: 57 additions & 3 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,74 @@
extern crate proc_macro;

use syn::{parse_macro_input, ItemFn, Attribute, FnArg, parse_quote, DeriveInput};
use syn::{parse_macro_input, parse_quote, Attribute, DeriveInput, FnArg, Ident, ItemFn};
use syn::parse::{Parse, ParseStream, Result};
use proc_macro::TokenStream;
use quote::quote;

struct ApiMethodArgs {
js_name: Option<String>,
}

impl Parse for ApiMethodArgs {
fn parse(input: ParseStream) -> Result<Self> {
if input.is_empty() {
return Ok(ApiMethodArgs { js_name: None });
}

let content;
syn::parenthesized!(content in input);

if content.is_empty() {
return Ok(ApiMethodArgs { js_name: None });
}

let js_name = if let Ok(ident) = content.parse::<Ident>() {
ident.to_string()
}
else {
return Err(content.error("Expected identifier"));
};

Ok(ApiMethodArgs { js_name: Some(js_name) })
}
}

/// This macro adds the `#[wasm_bindgen]` attribute to the function
/// and adds a `fetcher: js_sys::Function` parameter to the function signature.
///
/// ## Usages
///
/// ```rust
/// // the method will be called `retrieveCAS` in the generated bindings
/// #[cfg_attr(target_arch = "wasm32", wasm::api_method(retrieveCAS))]
/// pub async fn retrieve_cas() -> Result<String, Error> {
/// // a `fetcher` variable is available
/// // if the target architecture is `wasm32`
/// }
///
/// // the method will be still called `update` in the generated bindings
/// #[cfg_attr(target_arch = "wasm32", wasm::api_method)]
/// pub async fn update() -> Result<String, Error> {
/// // a `fetcher` variable is available
/// // if the target architecture is `wasm32`
/// }
/// ```
#[proc_macro_attribute]
pub fn api_method(_args: TokenStream, input: TokenStream) -> TokenStream {
pub fn api_method(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args with ApiMethodArgs::parse);
let mut input = parse_macro_input!(input as ItemFn);
let vis = &input.vis;
let sig = &mut input.sig;
let block = &input.block;
let attrs = &mut input.attrs;

let wasm_bindgen_attr: Attribute = parse_quote!(#[wasm_bindgen::prelude::wasm_bindgen]);
let wasm_bindgen_attr: Attribute = if let Some(name) = args.js_name {
parse_quote!(#[wasm_bindgen::prelude::wasm_bindgen(js_name = #name)])
}
else {
parse_quote!(#[wasm_bindgen::prelude::wasm_bindgen])
};

attrs.push(wasm_bindgen_attr);

let fetcher_param: FnArg = parse_quote!(fetcher: js_sys::Function);
Expand Down

0 comments on commit cf8d900

Please sign in to comment.