auto_enums
A library for to allow multiple return types by automatically generated enum.
This crate is a procedural macro implementation of the features discussions in rust-lang/rfcs#2414. This idea is also known as "Anonymous sum types".
This library provides the following attribute macros:
-
#[auto_enum]
Parses syntax, creates the enum, inserts variants, and passes specified traits to
#[enum_derive]
. -
#[enum_derive]
Implements specified traits to the enum.
Usage
Add this to your Cargo.toml
:
[dependencies]
auto_enums = "0.8"
Compiler support: requires rustc 1.56+
Examples
#[auto_enum]
's basic feature is to wrap the value returned by the obvious
branches (match
, if
, return
, etc..) by an enum that implemented the
specified traits.
use auto_enums::auto_enum;
#[auto_enum(Iterator)]
fn foo(x: i32) -> impl Iterator<Item = i32> {
match x {
0 => 1..10,
_ => vec![5, 10].into_iter(),
}
}
#[auto_enum]
generates code in two stages.
First, #[auto_enum]
will do the following.
- parses syntax
- creates the enum
- inserts variants
Code like this will be generated:
fn foo(x: i32) -> impl Iterator<Item = i32> {
#[::auto_enums::enum_derive(Iterator)]
enum __Enum1<__T1, __T2> {
__T1(__T1),
__T2(__T2),
}
match x {
0 => __Enum1::__T1(1..10),
_ => __Enum1::__T2(vec![5, 10].into_iter()),
}
}
Next, #[enum_derive]
implements the specified traits.
Code like this will be generated
#[auto_enum]
can also parse nested arms/branches by using the #[nested]
attribute.
use auto_enums::auto_enum;
#[auto_enum(Iterator)]
fn foo(x: i32) -> impl Iterator<Item = i32> {
match x {
0 => 1..10,
#[nested]
_ => match x {
1 => vec![5, 10].into_iter(),
_ => 0..=x,
},
}
}
See documentation for more details.
Supported traits
#[enum_derive]
implements the supported traits and passes unsupported
traits to #[derive]
.
#[enum_derive]
supports many of the standard library traits and some popular
third-party libraries traits such as rayon, futures,
tokio. See documentation for a complete list of supported traits.
If you want to use traits that are not supported by #[enum_derive]
, you
can use another crate that provides derives macros, or
you can define derives macros yourself (derive_utils probably can help it).
Basic usage of #[enum_derive]
use auto_enums::enum_derive;
// `#[enum_derive]` implements `Iterator`, and `#[derive]` implements `Clone`.
#[enum_derive(Iterator, Clone)]
enum Foo<A, B> {
A(A),
B(B),
}
Optional features
std
(enabled by default)- Enable to use
std
library's traits.
- Enable to use
ops
- Enable to use
[std|core]::ops
'sDeref
,DerefMut
,Index
,IndexMut
, andRangeBounds
traits.
- Enable to use
convert
- Enable to use
[std|core]::convert
'sAsRef
andAsMut
traits.
- Enable to use
fmt
- Enable to use
[std|core]::fmt
's traits other thanDebug
,Display
andWrite
.
- Enable to use
transpose_methods
- Enable to use
transpose*
methods.
- Enable to use
futures03
- Enable to use futures v0.3 traits.
futures01
- Enable to use futures v0.1 traits.
rayon
- Enable to use rayon traits.
serde
- Enable to use serde traits.
tokio1
- Enable to use tokio v1 traits.
tokio03
- Enable to use tokio v0.3 traits.
tokio02
- Enable to use tokio v0.2 traits.
tokio01
- Enable to use tokio v0.1 traits.
generator_trait
- Enable to use
[std|core]::ops::Generator
trait. - Note that this feature is unstable and may cause incompatible changes between patch versions.
- Enable to use
fn_traits
- Enable to use
[std|core]::ops
'sFn
,FnMut
, andFnOnce
traits. - Note that this feature is unstable and may cause incompatible changes between patch versions.
- Enable to use
trusted_len
- Enable to use
[std|core]::iter::TrustedLen
trait. - Note that this feature is unstable and may cause incompatible changes between patch versions.
- Enable to use
type_analysis
feature
Analyze return type of function and let
binding.
Note that this feature is still experimental.
Examples:
use auto_enums::auto_enum;
#[auto_enum] // there is no need to specify std library's traits
fn func1(x: i32) -> impl Iterator<Item = i32> {
match x {
0 => 1..10,
_ => vec![5, 10].into_iter(),
}
}
#[auto_enum]
fn func2(x: i32) {
// Unlike `feature(impl_trait_in_bindings)`, this works on stable compilers.
#[auto_enum]
let iter: impl Iterator<Item = i32> = match x {
0 => Some(0).into_iter(),
_ => 0..x,
};
}
Please be careful if you return another traits with the same name.
Related Projects
- derive_utils: A procedural macro helper for easily writing derives macros for enums.
- io-enum: #[derive(Read, Write, Seek, BufRead)] for enums.
- iter-enum: #[derive(Iterator, DoubleEndedIterator, ExactSizeIterator, Extend)] for enums.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.