#macro-derive #enums #proc-macro #macro #attributes #derive

nightly macro no-std auto_enums

A library for to allow multiple return types by automatically generated enum

55 releases

0.8.6 Aug 23, 2024
0.8.5 Jan 27, 2024
0.8.3 Oct 21, 2023
0.8.1 Jun 29, 2023
0.3.2 Dec 27, 2018

#303 in Rust patterns

Download history 44465/week @ 2024-08-24 52510/week @ 2024-08-31 44772/week @ 2024-09-07 43202/week @ 2024-09-14 44957/week @ 2024-09-21 45511/week @ 2024-09-28 38788/week @ 2024-10-05 49800/week @ 2024-10-12 56675/week @ 2024-10-19 56519/week @ 2024-10-26 61186/week @ 2024-11-02 43242/week @ 2024-11-09 47944/week @ 2024-11-16 51358/week @ 2024-11-23 65338/week @ 2024-11-30 54691/week @ 2024-12-07

227,196 downloads per month
Used in 127 crates (19 directly)

Apache-2.0 OR MIT

185KB
3.5K SLoC

auto_enums

crates.io docs.rs license msrv github actions

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"

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, 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),
}

Optional features

  • std (enabled by default)
    • Enable to use std library's traits.
  • ops
    • Enable to use [std|core]::ops's Deref, DerefMut, Index, IndexMut, and RangeBounds traits.
  • convert
    • Enable to use [std|core]::convert's AsRef and AsMut traits.
  • fmt
    • Enable to use [std|core]::fmt's traits other than Debug, Display and Write.
  • transpose_methods
    • Enable to use transpose* methods.
  • futures03
  • futures01
  • rayon
    • Enable to use rayon traits.
  • serde
    • Enable to use serde traits.
  • tokio1
  • tokio03
  • tokio02
  • tokio01
  • http_body1
  • coroutine_trait
    • Enable to use [std|core]::ops::Coroutine trait.
    • Note that this feature is unstable and may cause incompatible changes between patch versions.
  • fn_traits
    • Enable to use [std|core]::ops's Fn, FnMut, and FnOnce traits.
    • Note that this feature is unstable and may cause incompatible changes between patch versions.
  • trusted_len
    • Enable to use [std|core]::iter::TrustedLen trait.
    • Note that this feature is unstable and may cause incompatible changes between patch versions.

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.

  • 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.

Dependencies

~250–690KB
~16K SLoC