bitwarden_error_macro/basic/
attribute.rs

1use quote::quote;
2
3pub(crate) fn bitwarden_error_basic(
4    input: &syn::DeriveInput,
5    type_identifier: &proc_macro2::Ident,
6    export_as_identifier: &proc_macro2::Ident,
7) -> proc_macro::TokenStream {
8    let wasm =
9        cfg!(feature = "wasm").then(|| basic_error_wasm(type_identifier, export_as_identifier));
10    quote! {
11        #input
12
13        #wasm
14    }
15    .into()
16}
17
18fn basic_error_wasm(
19    type_identifier: &proc_macro2::Ident,
20    export_as_identifier: &proc_macro2::Ident,
21) -> proc_macro2::TokenStream {
22    let export_as_identifier_str = export_as_identifier.to_string();
23    let is_error_function_name = format!("is{}", export_as_identifier);
24    let ts_code_str = format!(
25        r##"r#"
26            export interface {export_as_identifier} extends Error {{
27                name: "{export_as_identifier}";
28            }};
29
30            export function {is_error_function_name}(error: any): error is {export_as_identifier};
31        "#"##
32    );
33    let ts_code: proc_macro2::TokenStream = ts_code_str
34        .parse()
35        .expect("Could not generate TypeScript code");
36
37    quote! {
38        const _: () = {
39            use bitwarden_error::wasm_bindgen::prelude::*;
40            use bitwarden_error::wasm_bindgen as wasm_bindgen;
41
42            #[wasm_bindgen(typescript_custom_section)]
43            const TS_APPEND_CONTENT: &'static str = #ts_code;
44
45            #[wasm_bindgen(js_name = #is_error_function_name, skip_typescript)]
46            pub fn is_error(error: &JsValue) -> bool {
47                let name_js_value = ::bitwarden_error::js_sys::Reflect::get(&error, &JsValue::from_str("name")).unwrap_or(JsValue::NULL);
48                let name = name_js_value.as_string().unwrap_or_default();
49                name == #export_as_identifier_str
50            }
51
52            #[automatically_derived]
53            impl From<#type_identifier> for JsValue {
54                fn from(error: #type_identifier) -> Self {
55                    let js_error = ::bitwarden_error::wasm::SdkJsError::new(error.to_string());
56                    js_error.set_name(#export_as_identifier_str.to_owned());
57                    js_error.into()
58                }
59            }
60        };
61    }
62}