integral-enum 2.1.0

Simple way to define integer-like enums
Documentation
# Integral enum

A simple way to define integer-like enums.
This macro implements bunch of traits that are usually implemented via looooong `derive(..)` attribute.

# Tour

## IntegralEnum

By default [`IntegralEnum`] assumes that you want all trait implementations: `PartialOrd`, `Ord`, `PartialEq`, `Eq`, `Debug`, `Clone`, `Copy`, `TryFrom`

```rust
use integral_enum::IntegralEnum;

#[derive(IntegralEnum)]
pub enum Sex {
    Male,
    Female,
}

assert_ne!(Sex::Male, Sex::Female);
assert!(Sex::Female > Sex::Male);
assert_eq!(Sex::try_from(0), Ok(Sex::Male));
assert_eq!(format!("{:?}", Sex::Male), "Male");
assert_eq!(Sex::Female.clone(), Sex::Female);
```

But you may disable some implementations by applying the `#[enum_disable(..)]` attribute (this will fail to compile due to disabled `Debug` trait implementation):

```rust compile_fail
#[derive(IntegralEnum)]
#[enum_disable(debug)]
pub enum Sex {
    Male,
    Female,
}

assert_eq!(format!("{:?}", Sex::Male), "Male");
```

This is useful if you want to compose [`IntegralEnum`] with some other macro or your own trait implementations, consider example with the `thiserror::Error` macro
(**IT IS MARKED AS COMPILE FAIL ONLY DUE TO LACK OF `thiserror` DEPENDENCY**):

```rust compile_fail
use integral_enum::IntegralEnum;
use thiserror::Error;

#[derive(IntegralEnum, Error)]
pub enum SendError {
    #[error("The remote side is closed connection")]
    Closed,

    #[error("Client with specified id was not found")]
    NotFound,
}
```

## StrictIntegralEnum

On the other hand you may want to enable __certain__ implementations, here the [`StrictIntegralEnum`] serves you:

```rust
use integral_enum::StrictIntegralEnum;

#[derive(StrictIntegralEnum)]
#[enum_impl(debug, partial_eq, try_from)]
pub enum Sex {
    Male,
    Female
}

assert_eq!(Sex::try_from(0), Ok(Sex::Male));
```

There's no other real use-case other than implementing the `try_from`, but I left possibility to autoimplement other traits for convenience.

## Dependencies

Some traits are depending on others, for example `Copy` depends on `Clone`, so, if you disable `Clone` implementation, then `Copy` implementation will be disabled too. For strict enums rules are the same, but differs in details: if you enable `Clone` implementation it will not enable the `Copy`. So, here the dependencies:

- `Clone` depends on `Copy`
- `Eq` depends on `PartialEq`
- `PartialOrd` depends on `Eq`, `Copy`
- `Ord` depends on `PartialOrd`

# Limitations

`IntegralEnum` tries to determine the discriminant exact type based on the following conditions:
- `#[repr(..)]` attribute
- deducing by the number of variants

And there's no type inference, **wontfix**.

So, macro will generate wrong code if there is no `#[repr(..)]` or discriminant type will deduced wrongly. It is quite hard to infer exact discriminant type with the only AST data, consider the following examples:

```rust
// Deduction is not watching to the enum tag's values
// (it is quite hard or even impossible to do it the correct way as stated above, 
//  since tags are just expressions, whose types we can't precisely infer and it just,
//  overcomplicated? This crate is not a all-in solution, just simple pattern implementation,
//  own type-inference will be overkill)
pub enum U16Tag {
    Tag = 0xFF_FF,
}
```