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