Crates.io | auto_enums |
lib.rs | auto_enums |
version | 0.8.6 |
source | src |
created_at | 2018-12-12 18:21:20.278758 |
updated_at | 2024-08-23 17:20:43.043586 |
description | A library for to allow multiple return types by automatically generated enum. |
homepage | |
repository | https://github.com/taiki-e/auto_enums |
max_upload_size | |
id | 101643 |
size | 341,802 |
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.
Add this to your Cargo.toml
:
[dependencies]
auto_enums = "0.8"
#[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.
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.
#[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, http_body. 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),
}
std
(enabled by default)
std
library's traits.ops
[std|core]::ops
's Deref
, DerefMut
, Index
, IndexMut
, and RangeBounds
traits.convert
[std|core]::convert
's AsRef
and AsMut
traits.fmt
[std|core]::fmt
's traits other than Debug
, Display
and Write
.transpose_methods
transpose*
methods.futures03
futures01
rayon
serde
tokio1
tokio03
tokio02
tokio01
http_body1
coroutine_trait
[std|core]::ops::Coroutine
trait.fn_traits
[std|core]::ops
's Fn
, FnMut
, and FnOnce
traits.trusted_len
[std|core]::iter::TrustedLen
trait.type_analysis
featureAnalyze 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.
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.