Skip to content

Commit

Permalink
feat: Move coerce_macro into module and add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmah309 committed Jul 19, 2024
1 parent 7716082 commit d1a1a83
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 217 deletions.
82 changes: 2 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/mcmah309/error_set/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/mcmah309/error_set/actions?query=branch%3Amaster)


A concise way to define errors and ergonomically coerce a subset into a superset with with just `.into()` or `?`, and coerce between intersecting sets with `coerce!`.
A concise way to define errors and ergonomically coerce a subset into a superset with with just `.into()` or `?`.

`error_set` was inspired by zig's [error set](https://ziglang.org/documentation/master/#Error-Set-Type)
and works functionally the same.
Expand Down Expand Up @@ -500,82 +500,4 @@ fn main() {
}
}
```
</details>

## The `coerce!` Macro
The `coerce!` macro handles coercing between intersecting sets (sets where some of the error types are in common). This allows only being explicit where relevant, such as the disjointedness.
e.g. given:
```rust
error_set! {
SetX = {
X
} || Common;
SetY = {
Y
} || Common;
Common = {
A,
B,
C,
D,
E,
F,
G,
H,
};
}
```
rather than writting:
```rust
fn setx_result_to_sety_result() -> Result<(), SetY> {
let _ok = match setx_result() {
Ok(ok) => ok,
Err(SetX::X) => {} // handle disjointedness
Err(SetX::A) => {
return Err(SetY::A);
}
Err(SetX::B) => {
return Err(SetY::B);
}
Err(SetX::C) => {
return Err(SetY::C);
}
Err(SetX::D) => {
return Err(SetY::D);
}
Err(SetX::E) => {
return Err(SetY::E);
}
Err(SetX::F) => {
return Err(SetY::F);
}
Err(SetX::G) => {
return Err(SetY::G);
}
Err(SetX::H) => {
return Err(SetY::H);
}
};
Ok(())
}
```
one can write this, which compiles to the `match` statement above:
```rust
fn setx_result_to_sety_result() -> Result<(),SetY> {
let _ok = coerce!(setx_result() => {
Ok(ok) => ok,
Err(SetX::X) => {}, // handle disjointedness
{ Err(SetX) => return Err(SetY) } // terminal coercion
});
Ok(())
}
```
The `coerce!` macro is a flat fast (no tt muncher 🦫) declarative macro created by the `error_set!` macro for the set.
`coerce!` behaves like a regular `match` statement, except it allows a terminal coercion statement between sets. e.g.
```rust
{ Err(SetX) => return Err(SetY) }
{ Err(SetX) => Err(SetY) }
{ SetX => return SetY }
{ SetX => SetY }
```
With `coerce!`, one can concisely handle specific variants of errors as they bubble up the call stack and propagate the rest.
</details>
Loading

0 comments on commit d1a1a83

Please sign in to comment.