errify_macros/lib.rs
1mod errify_macro;
2mod input;
3mod output;
4
5use proc_macro::TokenStream;
6
7use crate::errify_macro::{errify_impl, errify_with_impl};
8
9/// Macro that provides error context on entire function.
10/// Supports `async` functions.
11///
12/// Constraints are `T: Display + Send + Sync + 'static` and `E: WrapErr`.
13///
14/// # Syntax
15/// ```text
16/// #[errify( $( $fmt:literal $(, $arg:expr)* ) | $expr:expr )]
17/// ```
18///
19/// # Usage example
20///
21/// ### Format string with arguments
22/// ```ignore
23/// use errify::errify;
24///
25/// #[errify("Custom error context, with argument capturing {arg} = {}", arg)]
26/// fn func(arg: i32) -> Result<(), CustomError> {
27/// // ...
28/// }
29/// ```
30///
31/// ### Expression
32/// ```ignore
33/// use errify::errify;
34///
35/// #[errify(String::from("Custom error context"))]
36/// fn func(arg: i32) -> Result<(), CustomError> {
37/// // ...
38/// }
39/// ```
40#[proc_macro_attribute]
41pub fn errify(args: TokenStream, input: TokenStream) -> TokenStream {
42 match errify_impl(args.into(), input.into()) {
43 Ok(tokens) => tokens.into(),
44 Err(diag) => diag.emit_as_expr_tokens().into(),
45 }
46}
47
48/// Macro that provides lazy error context on entire function.
49/// Supports `async` functions.
50///
51/// Constraint is `F: FnOnce() -> impl Display + Send + Sync + 'static` and `E: WrapErr`.
52///
53/// # Syntax
54/// ```text
55/// #[errify_with( $closure:expr | $func:ident )]
56/// ```
57///
58/// # Usage example
59///
60/// ### Closure
61/// ```ignore
62/// use errify::errify_with;
63///
64/// #[errify_with(|| "Custom error context from closure")]
65/// fn func(arg: i32) -> Result<(), CustomError> {
66/// // ...
67/// }
68/// ```
69///
70/// ### Function
71/// ```ignore
72/// use errify::errify_with;
73///
74/// fn context_provider() -> impl Display { "Context from function" }
75///
76/// #[errify_with(context_provider)]
77/// fn func(arg: i32) -> Result<(), CustomError> {
78/// // ...
79/// }
80/// ```
81#[proc_macro_attribute]
82pub fn errify_with(args: TokenStream, input: TokenStream) -> TokenStream {
83 match errify_with_impl(args.into(), input.into()) {
84 Ok(tokens) => tokens.into(),
85 Err(diag) => diag.emit_as_expr_tokens().into(),
86 }
87}