bitwarden_error_macro/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
mod args;
mod attribute;
mod basic;
mod flat;
mod full;
/// A procedural macro for generating error types with customizable serialization behavior.
///
/// # Attributes
///
/// ## Error type
/// - `basic`: The error is converted into a string using the `ToString` trait.
/// - `flat`: The error is converted into a flat structure using the `FlatError` trait.
/// - `full`: The entire error stack is made available using `serde`.
///
/// ## Export as
///
/// `export_as`: The name of the exported TypeScript type. If not provided, the name of the Rust
/// type is used. Note: This attribute is only available when using the `basic` and `flat` error
/// types.
///
/// # Examples
///
/// ## Basic
/// Using the `basic` error type:
///
/// ```rust
/// use bitwarden_error::prelude::*;
/// use thiserror::Error;
///
/// #[derive(Debug, Error)]
/// #[bitwarden_error(basic)]
/// enum MyError {
/// #[error("Not found")]
/// NotFound,
/// #[error("Permission denied")]
/// PermissionDenied,
/// }
/// ```
///
/// will generate the following TypeScript definition:
///
/// ```typescript
/// export interface MyError extends Error {
/// name: "MyError";
/// }
/// ```
///
/// ## Flat
///
/// Using the `flat` error type:
///
/// ```rust
/// use bitwarden_error::prelude::*;
/// use thiserror::Error;
///
/// #[derive(Debug, Error)]
/// #[bitwarden_error(basic)]
/// enum MyError {
/// #[error("Not found")]
/// NotFound,
/// #[error("Permission denied")]
/// PermissionDenied,
/// }
/// ```
///
/// will generate the following TypeScript definition:
///
/// ```typescript
/// export interface MyError extends Error {
/// name: "MyError";
/// variant: "NotFound" | "PermissionDenied";
/// }
/// ```
///
/// Using the `full` error type:
///
/// ```rust
/// use bitwarden_error::prelude::*;
/// use serde::Serialize;
/// use thiserror::Error;
///
/// #[bitwarden_error(full)]
/// #[derive(Debug, Error)]
/// #[error("Vault is locked")]
/// struct VaultLocked;
///
/// #[derive(Debug, Serialize)]
/// struct ExternalError;
///
/// #[bitwarden_error(full)]
/// #[derive(Debug, Error)]
/// enum MyError {
/// #[error(transparent)]
/// VaultLocked(#[from] VaultLocked),
/// #[error("External error")]
/// ExternalError(ExternalError),
/// }
/// ```
///
/// will use tsify_next::Tsify to generate roughly the following TypeScript definition:
///
/// ```typescript
/// export type CryptoError =
/// | { MissingFieldError: MissingFieldError }
/// | { VaultLocked: VaultLocked };
///
/// export interface VaultLocked { }
/// ```
///
/// All the general interopability rules apply such as external types needing to be defined as
/// custom types.
#[proc_macro_attribute]
pub fn bitwarden_error(
args: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
attribute::bitwarden_error(args, item)
}