Skip to content

Commit

Permalink
Update README with some recent features (#108)
Browse files Browse the repository at this point in the history
* Update README with some recent features

* Enable complex-expressions for doc tests
  • Loading branch information
illicitonion authored Feb 24, 2023
1 parent 3638efa commit 4b38288
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path=num_enum/Cargo.toml --features=external_doc --doc
args: --manifest-path=num_enum/Cargo.toml --features=external_doc,complex-expressions --doc
toolchain: ${{ matrix.toolchain }}
- name: Fmt
uses: actions-rs/cargo@v1
Expand Down
70 changes: 68 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,34 @@ fn main() {
}
```

Range expressions are also supported for alternatives, but this requires enabling the `complex-expressions` feature:

```rust
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;

#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
enum Number {
Zero = 0,
#[num_enum(alternatives = [2..16])]
Some = 1,
#[num_enum(alternatives = [17, 18..=255])]
Many = 16,
}

fn main() {
let zero = Number::try_from(0u8);
assert_eq!(zero, Ok(Number::Zero));

let some = Number::try_from(15u8);
assert_eq!(some, Ok(Number::Some));

let many = Number::try_from(255u8);
assert_eq!(many, Ok(Number::Many));
}
```

Default variant
---------------

Expand Down Expand Up @@ -130,8 +158,13 @@ fn main() {
Safely turning a primitive into an exhaustive enum with from_primitive
-------------------------------------------------------------

If your enum has all possible primitive values covered by the use of a variant marked `#[num_enum(default)]`,
you can derive `FromPrimitive` for it (which auto-implement stdlib's `From`):
If your enum has all possible primitive values covered, you can derive `FromPrimitive` for it (which auto-implement stdlib's `From`):

You can cover all possible values by:
* Having variants for every possible value
* Having a variant marked `#[num_enum(default)]`
* Having a variant marked `#[num_enum(catch_all)]`
* Having `#[num_enum(alternatives = [...])`s covering values not covered by a variant.

```rust
use num_enum::FromPrimitive;
Expand All @@ -156,6 +189,39 @@ fn main() {
}
```

Catch-all variant
-----------------

Sometimes it is desirable to have an `Other` variant which holds the otherwise un-matched value as a field.

The `#[num_enum(catch_all)]` attribute allows you to mark at most one variant for this purpose. The variant it's applied to must be a tuple variant with exactly one field matching the `repr` type.

```rust
use num_enum::FromPrimitive;
use std::convert::TryFrom;

#[derive(Debug, Eq, PartialEq, FromPrimitive)]
#[repr(u8)]
enum Number {
Zero = 0,
#[num_enum(catch_all)]
NonZero(u8),
}

fn main() {
let zero = Number::from(0u8);
assert_eq!(zero, Number::Zero);

let one = Number::from(1u8);
assert_eq!(one, Number::NonZero(1_u8));

let two = Number::from(2u8);
assert_eq!(two, Number::NonZero(2_u8));
}
```

As this is naturally exhaustive, this is only supported for `FromPrimitive`, not also `TryFromPrimitive`.

Unsafely turning a primitive into an enum with from_unchecked
-------------------------------------------------------------

Expand Down

0 comments on commit 4b38288

Please sign in to comment.