Skerry: Super Kool ERRors Yoh
Example:
use *;
// There can be only one #[sherry_mod] in your project
// Generates a CheckAuthError enum automatically
>
;
// This allows #[skerry_fn] to run on impl blocks
// Manually define composite errors like this
define_error!;
Core Workflow
- Define all possible error structs in a
#[skerry_mod]. - Mark functions with
#[skerry_fn]. - Use the
*operator to bubble up errors from sub-functions without manually mapping variants.
The Error Module
Every project needs one module (usually errors.rs) that acts as the source of truth.
// Recommended to be pub for easier macro expansions
pub use *;
You can also anotate with #[from] to automatically add conversions from the inner type.
This is only valid for tuple structs with a single element.
Note: When using errors in any other file, import them via crate::errors::*; instead
of individual imports to ensure the macros can resolve the paths correctly.
Function-Specific Enums
By using #[skerry_fn], you define a return type using a tuple of error structs.
Skerry transforms this into a unique enum named {FunctionName}Error.
>
The Asterisk (*) Expansion
When you put *OtherFnError in your return array it pulls all
variants from OtherFnError into your current function's list.
- Deduplication: Variants are deduplicated automatically. If
ErrAis added manually and also exists inside a*expansion, only one variant is generated.
>
The syntax below has the exact same effects, *LowLevelError is nothing more than syntatic sugar
>
In the cases above the generated enum looks like this
Using Skerry inside Impl Blocks
Skerry provides the #[skerry_impl] attribute to handle methods within impl blocks.
This attribute coordinates with #[skerry_fn] to split the generated code
so error enums are generated outside the impl block.
Example
;
// Optional prefix for functions inside impl block
Using Skerry inside Trait Blocks
Skerry provides the #[skerry_trait] attribute to handle methods within trait blocks.
This attribute coordinates with #[skerry_fn] to split the generated code
so error enums are generated outside the trait block.
Example
// Optional prefix for functions inside trait block
Manual Error Definitions
Manually define composite errors using the define_error! macro.
This allows you to skip needing a function to define errors.
Example
define_error!;
Custom Result Feature
The custom_result feature implements a specialized result type and leverages the
unstable features to enable even more automation.
Nightly Features Required
To use the full suite of automation provided by this feature, you must enable the following nightly features in your crate root:
Overview
Enabling custom_result changes the behavior of the ? operator to support
automatic conversion into GlobalErrors<I>.
| Feature Gate | Effect |
|---|---|
try_trait_v2 |
Allows using ? with custom Result types; removes the strict requirement for #[skerry_fn] on standard functions. |
custom_inner_attributes/proc_macro_hygiene |
Enables the use of #![skerry] at the top of a file to annotate all contents automatically. |
Error Declaration
Use #![skerry_mod] to define concise error sets. The #[from] attribute allows
automatic wrapping of external library errors.
//! errors.rs
;
;
;
Comparison
Standard Manual Approach
Traditionally, every function and implementation block requires explicit tagging:
>
;
Automated Approach with custom_result
By adding #![skerry] to the top of your module, the boilerplate is handled
automatically.
>
;
Compile-Time Safety
Skerry uses a custom trait system (MissingConvert) to verify error bounds at
compile-time. If you try to use ? on a function whose errors are not represented
in your current return tuple, the compiler will refuse to build.
License: MIT