Easy Macros
Use the parent crate instead.
What is this?
#[always_context] attribute automatically adds .with_context(context!()) to all ? operators that don't already have context, eliminating the need to manually add context to every fallible operation.
Basic Usage
use always_context;
use Result;
How It Works
The #[always_context] attribute automatically transforms:
// From this:
let result = operation?;
// To this:
let result = operation.with_context?;
Context includes:
- Function call with arguments
- File location and line number
- Formatted argument values
Attributes
Function-level Control
#[no_context]- Disable context generation entirely#[no_context_inputs]- Add context but exclude function arguments#[enable_context]- Re-enable context (useful in macros where it's auto-disabled)
Argument-level Control
#[context(display)]- UseDisplayinstead ofDebugfor argument formatting#[context(.method())]- Call method on argument before displaying#[context(tokens)]- Format as token stream (for proc-macro arguments)#[context(ignore)]- Exclude this argument from context
Requirements
- Function must return
anyhow::Result<T>orResult<T, UserFriendlyError> - Only processes
?operators that don't already have context methods
Unsupported Syntax
These expressions before ? require manual .with_context():
- Blocks:
{ expr }? - Control flow:
if ... {}?,match ... {}?,while ... {}?,for ... {}?,loop { ... }? - Field access:
obj.field? - Macros:
macro!()?
Features
easy-sql- Adds#[context(not_sql)]attribute for SQL macro integration