-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into km/pm-12400/private-key-regen
- Loading branch information
Showing
32 changed files
with
988 additions
and
79 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
[package] | ||
name = "bitwarden-error-macro" | ||
version.workspace = true | ||
authors.workspace = true | ||
edition.workspace = true | ||
rust-version.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
license-file.workspace = true | ||
keywords.workspace = true | ||
|
||
[features] | ||
wasm = ["bitwarden-error/wasm"] | ||
|
||
[dependencies] | ||
darling = "0.20.10" | ||
proc-macro2 = "1.0.89" | ||
quote = "1.0.37" | ||
syn = "2.0.87" | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dev-dependencies] | ||
bitwarden-error.workspace = true | ||
serde.workspace = true | ||
thiserror.workspace = true | ||
tsify-next.workspace = true | ||
js-sys.workspace = true | ||
wasm-bindgen.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use darling::FromMeta; | ||
|
||
#[derive(FromMeta)] | ||
pub(crate) struct BitwardenErrorArgs { | ||
#[darling(flatten)] | ||
pub error_type: BitwardenErrorType, | ||
|
||
#[darling(default)] | ||
pub export_as: Option<String>, | ||
} | ||
|
||
#[derive(FromMeta)] | ||
#[darling(rename_all = "snake_case")] | ||
pub(crate) enum BitwardenErrorType { | ||
/// The error is going to be converted into a string using the `ToString` trait | ||
Basic, | ||
|
||
/// The error is going to be converted into a flat error using the `FlatError` trait | ||
Flat, | ||
|
||
/// The entire error stack is going to be made available using `serde` | ||
Full, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use darling::{ast::NestedMeta, FromMeta}; | ||
use quote::format_ident; | ||
|
||
use crate::args::{BitwardenErrorArgs, BitwardenErrorType}; | ||
|
||
pub(crate) fn bitwarden_error( | ||
args: proc_macro::TokenStream, | ||
item: proc_macro::TokenStream, | ||
) -> proc_macro::TokenStream { | ||
let attr_args = match NestedMeta::parse_meta_list(args.into()) { | ||
Ok(v) => v, | ||
Err(e) => { | ||
return proc_macro::TokenStream::from(darling::Error::from(e).write_errors()); | ||
} | ||
}; | ||
|
||
let args = match BitwardenErrorArgs::from_list(&attr_args) { | ||
Ok(params) => params, | ||
Err(error) => { | ||
return proc_macro::TokenStream::from(error.write_errors()); | ||
} | ||
}; | ||
|
||
let input = syn::parse_macro_input!(item as syn::DeriveInput); | ||
let type_identifier = &input.ident; | ||
let export_as_identifier = &args | ||
.export_as | ||
.as_ref() | ||
.map(|export_as| format_ident!("{}", export_as)) | ||
.unwrap_or(input.ident.clone()); | ||
|
||
match args.error_type { | ||
BitwardenErrorType::Basic => crate::basic::attribute::bitwarden_error_basic( | ||
&input, | ||
type_identifier, | ||
export_as_identifier, | ||
), | ||
BitwardenErrorType::Flat => crate::flat::attribute::bitwarden_error_flat( | ||
&input, | ||
type_identifier, | ||
export_as_identifier, | ||
), | ||
BitwardenErrorType::Full => crate::full::attribute::bitwarden_error_full( | ||
&input, | ||
type_identifier, | ||
export_as_identifier, | ||
), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use quote::quote; | ||
|
||
pub(crate) fn bitwarden_error_basic( | ||
input: &syn::DeriveInput, | ||
type_identifier: &proc_macro2::Ident, | ||
export_as_identifier: &proc_macro2::Ident, | ||
) -> proc_macro::TokenStream { | ||
let wasm = | ||
cfg!(feature = "wasm").then(|| basic_error_wasm(type_identifier, export_as_identifier)); | ||
quote! { | ||
#input | ||
|
||
#wasm | ||
} | ||
.into() | ||
} | ||
|
||
fn basic_error_wasm( | ||
type_identifier: &proc_macro2::Ident, | ||
export_as_identifier: &proc_macro2::Ident, | ||
) -> proc_macro2::TokenStream { | ||
let export_as_identifier_str = export_as_identifier.to_string(); | ||
let is_error_function_name = format!("is{}", export_as_identifier); | ||
let ts_code_str = format!( | ||
r##"r#" | ||
export interface {export_as_identifier} extends Error {{ | ||
name: "{export_as_identifier}"; | ||
}}; | ||
export function {is_error_function_name}(error: any): error is {export_as_identifier}; | ||
"#"## | ||
); | ||
let ts_code: proc_macro2::TokenStream = ts_code_str | ||
.parse() | ||
.expect("Could not generate TypeScript code"); | ||
|
||
quote! { | ||
const _: () = { | ||
use bitwarden_error::wasm_bindgen::prelude::*; | ||
|
||
#[wasm_bindgen(typescript_custom_section)] | ||
const TS_APPEND_CONTENT: &'static str = #ts_code; | ||
|
||
#[wasm_bindgen(js_name = #is_error_function_name, skip_typescript)] | ||
pub fn is_error(error: &JsValue) -> bool { | ||
let name_js_value = bitwarden_error::js_sys::Reflect::get(&error, &JsValue::from_str("name")).unwrap_or(JsValue::NULL); | ||
let name = name_js_value.as_string().unwrap_or_default(); | ||
name == #export_as_identifier_str | ||
} | ||
|
||
#[automatically_derived] | ||
impl From<#type_identifier> for JsValue { | ||
fn from(error: #type_identifier) -> Self { | ||
let js_error = SdkJsError::new(error.to_string()); | ||
js_error.set_name(#export_as_identifier_str.to_owned()); | ||
js_error.into() | ||
} | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod attribute; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
use quote::quote; | ||
use syn::Data; | ||
|
||
pub(crate) fn bitwarden_error_flat( | ||
input: &syn::DeriveInput, | ||
type_identifier: &proc_macro2::Ident, | ||
export_as_identifier: &proc_macro2::Ident, | ||
) -> proc_macro::TokenStream { | ||
match &input.data { | ||
Data::Enum(data) => { | ||
let variant_names = data.variants.iter().map(|variant| &variant.ident); | ||
let match_arms = data.variants.iter().map(|variant| { | ||
let variant_ident = &variant.ident; | ||
let variant_str = variant_ident.to_string(); | ||
|
||
match variant.fields { | ||
syn::Fields::Unit => { | ||
quote! { | ||
#type_identifier::#variant_ident => #variant_str | ||
} | ||
} | ||
syn::Fields::Named(_) => { | ||
quote! { | ||
#type_identifier::#variant_ident { .. } => #variant_str | ||
} | ||
} | ||
syn::Fields::Unnamed(_) => { | ||
quote! { | ||
#type_identifier::#variant_ident(..) => #variant_str | ||
} | ||
} | ||
} | ||
}); | ||
|
||
let wasm = cfg!(feature = "wasm").then(|| { | ||
flat_error_wasm( | ||
type_identifier, | ||
export_as_identifier, | ||
&variant_names.collect::<Vec<_>>(), | ||
) | ||
}); | ||
|
||
quote! { | ||
#input | ||
#wasm | ||
|
||
#[automatically_derived] | ||
impl ::bitwarden_error::prelude::FlatError for #type_identifier { | ||
fn error_variant(&self) -> &'static str { | ||
match &self { | ||
#(#match_arms), * | ||
} | ||
} | ||
} | ||
} | ||
.into() | ||
} | ||
_ => syn::Error::new_spanned(input, "bitwarden_error can only be used with enums") | ||
.to_compile_error() | ||
.into(), | ||
} | ||
} | ||
|
||
fn flat_error_wasm( | ||
type_identifier: &proc_macro2::Ident, | ||
export_as_identifier: &proc_macro2::Ident, | ||
variant_names: &[&proc_macro2::Ident], | ||
) -> proc_macro2::TokenStream { | ||
let export_as_identifier_str = export_as_identifier.to_string(); | ||
let is_error_function_name = format!("is{}", export_as_identifier); | ||
let ts_variant_names = variant_names | ||
.iter() | ||
.map(|vn| format!(r#""{vn}""#)) | ||
.collect::<Vec<String>>() | ||
.join("|"); | ||
let ts_code_str = format!( | ||
r##"r#" | ||
export interface {export_as_identifier_str} extends Error {{ | ||
name: "{export_as_identifier_str}"; | ||
variant: {ts_variant_names}; | ||
}}; | ||
export function {is_error_function_name}(error: any): error is {export_as_identifier_str}; | ||
"#"##, | ||
); | ||
let ts_code: proc_macro2::TokenStream = ts_code_str | ||
.parse() | ||
.expect("Could not generate TypeScript code"); | ||
|
||
quote! { | ||
const _: () = { | ||
use bitwarden_error::wasm_bindgen::prelude::*; | ||
|
||
#[wasm_bindgen(typescript_custom_section)] | ||
const TS_APPEND_CONTENT: &'static str = #ts_code; | ||
|
||
#[wasm_bindgen(js_name = #is_error_function_name, skip_typescript)] | ||
pub fn is_error(error: &JsValue) -> bool { | ||
let name_js_value = bitwarden_error::js_sys::Reflect::get(&error, &JsValue::from_str("name")).unwrap_or(JsValue::NULL); | ||
let name = name_js_value.as_string().unwrap_or_default(); | ||
name == #export_as_identifier_str | ||
} | ||
|
||
#[automatically_derived] | ||
impl From<#type_identifier> for JsValue { | ||
fn from(error: #type_identifier) -> Self { | ||
let js_error = SdkJsError::new(error.to_string()); | ||
js_error.set_name(#export_as_identifier_str.to_owned()); | ||
js_error.set_variant(error.error_variant().to_owned()); | ||
js_error.into() | ||
} | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod attribute; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use darling::Error; | ||
use quote::quote; | ||
|
||
pub(crate) fn bitwarden_error_full( | ||
input: &syn::DeriveInput, | ||
type_identifier: &proc_macro2::Ident, | ||
export_as_identifier: &proc_macro2::Ident, | ||
) -> proc_macro::TokenStream { | ||
if type_identifier != export_as_identifier { | ||
return Error::custom("`bitwarden_error(full)` does not currently support `export_as`") | ||
.write_errors() | ||
.into(); | ||
} | ||
|
||
let wasm_attributes = cfg!(feature = "wasm").then(|| { | ||
quote! { | ||
#[derive(bitwarden_error::tsify_next::Tsify)] | ||
#[tsify(into_wasm_abi)] | ||
} | ||
}); | ||
|
||
quote! { | ||
#[derive(serde::Serialize)] | ||
#wasm_attributes | ||
#input | ||
} | ||
.into() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod attribute; |
Oops, something went wrong.