Skip to content

Commit 6728139

Browse files
committed
Separate macro and implement trait directly in the macro
1 parent 8836845 commit 6728139

File tree

7 files changed

+100
-20
lines changed

7 files changed

+100
-20
lines changed

crates/bitwarden-error-macro/src/lib.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ mod attribute;
55
mod basic;
66
mod flat;
77
mod full;
8-
mod wasm_ipc;
98

109
/// A procedural macro for generating error types with customizable serialization behavior.
1110
///
@@ -121,14 +120,3 @@ pub fn bitwarden_error(
121120
) -> proc_macro::TokenStream {
122121
attribute::bitwarden_error(args, item)
123122
}
124-
125-
#[proc_macro_attribute]
126-
pub fn bitwarden_wasm_ipc_channel(
127-
args: proc_macro::TokenStream,
128-
item: proc_macro::TokenStream,
129-
) -> proc_macro::TokenStream {
130-
match wasm_ipc::bitwarden_wasm_ipc_channel_internal(args, item) {
131-
Ok(v) => v,
132-
Err(e) => proc_macro::TokenStream::from(e.to_compile_error()),
133-
}
134-
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[package]
2+
name = "bitwarden-ffi-macros"
3+
description = """
4+
Internal crate for the bitwarden crate. Do not use.
5+
"""
6+
7+
version.workspace = true
8+
authors.workspace = true
9+
edition.workspace = true
10+
rust-version.workspace = true
11+
readme.workspace = true
12+
homepage.workspace = true
13+
repository.workspace = true
14+
license-file.workspace = true
15+
keywords.workspace = true
16+
17+
[features]
18+
wasm = []
19+
20+
[dependencies]
21+
darling = "0.20.10"
22+
proc-macro2 = "1.0.89"
23+
quote = "1.0.37"
24+
syn = "2.0.87"
25+
26+
[lints]
27+
workspace = true
28+
29+
[lib]
30+
proc-macro = true
31+
32+
[dev-dependencies]
33+
js-sys.workspace = true
34+
serde.workspace = true
35+
thiserror.workspace = true
36+
tsify-next.workspace = true
37+
wasm-bindgen.workspace = true

crates/bitwarden-ffi-macros/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Bitwarden WASM Macros
2+
3+
Provides utility macros for simplifying FFI with WebAssembly and UniFFI.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![doc = include_str!("../README.md")]
2+
3+
mod wasm_ipc;
4+
5+
#[proc_macro_attribute]
6+
pub fn bitwarden_wasm_ipc_channel(
7+
args: proc_macro::TokenStream,
8+
item: proc_macro::TokenStream,
9+
) -> proc_macro::TokenStream {
10+
match wasm_ipc::bitwarden_wasm_ipc_channel_internal(args, item) {
11+
Ok(v) => v,
12+
Err(e) => proc_macro::TokenStream::from(e.to_compile_error()),
13+
}
14+
}

crates/bitwarden-error-macro/src/wasm_ipc.rs renamed to crates/bitwarden-ffi-macros/src/wasm_ipc.rs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use darling::{ast::NestedMeta, FromMeta};
12
use proc_macro::TokenStream;
2-
use quote::ToTokens;
3+
use quote::{quote, ToTokens};
34
use syn::{
45
parse_quote, spanned::Spanned, Attribute, Error, FnArg, ForeignItem, ForeignItemFn, Ident,
56
ItemForeignMod, Pat, ReturnType, Type,
@@ -59,11 +60,20 @@ impl Func {
5960
}
6061
}
6162

63+
#[derive(FromMeta)]
64+
struct WasmIpcArgs {
65+
trait_impl: Option<syn::TypePath>,
66+
#[darling(default)]
67+
async_trait: bool,
68+
}
69+
6270
pub(crate) fn bitwarden_wasm_ipc_channel_internal(
63-
_args: TokenStream,
71+
attr: TokenStream,
6472
item: TokenStream,
6573
) -> Result<TokenStream, Error> {
6674
let mut input = syn::parse::<ItemForeignMod>(item)?;
75+
let attr_args = NestedMeta::parse_meta_list(attr.into())?;
76+
let attr_args = WasmIpcArgs::from_list(&attr_args)?;
6777

6878
// Validate the ABI
6979
match input.abi.name {
@@ -148,9 +158,13 @@ pub(crate) fn bitwarden_wasm_ipc_channel_internal(
148158
quote::quote! { #ident }
149159
});
150160

161+
let vis = attr_args.trait_impl.is_none().then(|| {
162+
quote::quote! { pub }
163+
});
164+
151165
quote::quote! {
152166
// TODO: Should these return a result?
153-
pub async fn #name(&self, #( #args ),*) -> #ret {
167+
#vis async fn #name(&self, #( #args ),*) -> #ret {
154168
let (tx, rx) = ::tokio::sync::oneshot::channel();
155169
self.sender.send(#channel_command_ident::#name {
156170
_internal_respond_to: tx,
@@ -161,6 +175,27 @@ pub(crate) fn bitwarden_wasm_ipc_channel_internal(
161175
}
162176
});
163177

178+
let channel_impl = if let Some(trait_impl) = &attr_args.trait_impl {
179+
let async_trait = attr_args.async_trait.then(|| {
180+
quote::quote! {
181+
#[async_trait::async_trait]
182+
}
183+
});
184+
185+
quote! {
186+
#async_trait
187+
impl #trait_impl for #channel_ident {
188+
#( #impls )*
189+
}
190+
}
191+
} else {
192+
quote! {
193+
impl #channel_ident {
194+
#( #impls )*
195+
}
196+
}
197+
};
198+
164199
let matches = functions.iter().map(|f| {
165200
let name = &f.name;
166201
let args: Vec<_> = f.args.iter().map(|(ident, _)| {
@@ -216,9 +251,7 @@ pub(crate) fn bitwarden_wasm_ipc_channel_internal(
216251
}
217252
}
218253

219-
impl #channel_ident {
220-
#( #impls )*
221-
}
254+
#channel_impl
222255
}
223256
.into())
224257
}

crates/bitwarden-wasm-internal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ async-trait = ">=0.1.80, <0.2"
2020
bitwarden-core = { workspace = true, features = ["wasm", "internal"] }
2121
bitwarden-crypto = { workspace = true, features = ["wasm"] }
2222
bitwarden-error = { workspace = true }
23+
bitwarden-ffi-macros = { workspace = true }
2324
bitwarden-ipc = { workspace = true, features = ["wasm"] }
2425
bitwarden-ssh = { workspace = true, features = ["wasm"] }
2526
bitwarden-vault = { workspace = true, features = ["wasm"] }

crates/bitwarden-wasm-internal/src/client.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ export interface CipherStore {
8484
}
8585
"#;
8686

87-
#[bitwarden_error::bitwarden_wasm_ipc_channel]
87+
#[bitwarden_ffi_macros::bitwarden_wasm_ipc_channel(
88+
trait_impl = "DataStore<Cipher>",
89+
async_trait = true
90+
)]
8891
#[wasm_bindgen]
8992
extern "C" {
9093
#[wasm_bindgen(js_name = CipherStore, typescript_type = "CipherStore")]
@@ -103,6 +106,7 @@ extern "C" {
103106
async fn remove(this: &JSCipherStore, id: String);
104107
}
105108

109+
/*
106110
#[async_trait::async_trait]
107111
impl DataStore<Cipher> for ChannelJSCipherStore {
108112
async fn get(&self, id: String) -> Option<Cipher> {
@@ -120,7 +124,7 @@ impl DataStore<Cipher> for ChannelJSCipherStore {
120124
async fn remove(&self, id: String) {
121125
ChannelJSCipherStore::remove(self, id).await;
122126
}
123-
}
127+
}*/
124128

125129
#[wasm_bindgen]
126130
impl StoreClient {

0 commit comments

Comments
 (0)