into_jsvalue_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput};
4
5/// A simple derive macro to implement From<T> for JsValue.
6#[proc_macro_derive(IntoJsValue)]
7pub fn into_jsvalue_derive(input: TokenStream) -> TokenStream {
8    let input = parse_macro_input!(input as DeriveInput);
9    let ident = input.ident;
10    let ident_str = ident.to_string();
11    let generics = input.generics;
12    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
13
14    // Adding where clause constraints for all generic types to implement serde::Serialize
15    let where_clause = match where_clause {
16        Some(where_clause) => quote! { #where_clause },
17        None => quote! {},
18    };
19
20    quote!(
21        impl #impl_generics From<#ident #ty_generics> for wasm_bindgen::JsValue #where_clause {
22            fn from(value: #ident #ty_generics) -> Self {
23                let res = serde_wasm_bindgen::to_value(&value);
24                wasm_bindgen::UnwrapThrowExt::expect_throw(
25                    res,
26                    &format!("failed to convert {} to a JsValue", #ident_str),
27                )
28            }
29        }
30    )
31    .into()
32}