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)
}