derive_utils

![crates-badge] ![docs-badge] ![license-badge] ![rustc-badge]

A procedural macro helper for easily writing derives macros for enums.

Usage

Add this to your Cargo.toml:

toml [dependencies] derive_utils = "0.11"

The current derive_utils requires Rust 1.31 or later.

Examples

[quick_derive!] macro make easy to write proc_macro_derive like deriving trait to enum so long as all variants are implemented that trait.

```rust use deriveutils::quickderive; use proc_macro::TokenStream;

[procmacroderive(Iterator)]

pub fn deriveiterator(input: TokenStream) -> TokenStream { quickderive! { input, // trait path std::iter::Iterator, // trait definition trait Iterator { type Item; fn next(&mut self) -> Option; fn size_hint(&self) -> (usize, Option); } } }

[procmacroderive(ExactSizeIterator)]

pub fn deriveexactsizeiterator(input: TokenStream) -> TokenStream { quickderive! { input, // trait path std::iter::ExactSizeIterator, // super trait's associated types , // trait definition trait ExactSizeIterator: Iterator { fn len(&self) -> usize; } } }

[procmacroderive(Future)]

pub fn derivefuture(input: TokenStream) -> TokenStream { quickderive! { input, // trait path std::future::Future, // trait definition trait Future { type Output; fn poll( self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll; } } } ```

Generated code

When deriving for enum like the following:

```rust

[derive(Iterator, ExactSizeIterator, Future)]

enum Enum { A(A), B(B), } ```

Code like this will be generated:

```rust enum Enum { A(A), B(B), }

impl std::iter::Iterator for Enum where A: std::iter::Iterator, B: std::iter::Iterator::Item>, { type Item = ::Item; fn next(&mut self) -> Option { match self { Enum::A(x) => x.next(), Enum::B(x) => x.next(), } } fn sizehint(&self) -> (usize, Option) { match self { Enum::A(x) => x.sizehint(), Enum::B(x) => x.size_hint(), } } }

impl std::iter::ExactSizeIterator for Enum where A: std::iter::ExactSizeIterator, B: std::iter::ExactSizeIterator::Item>, { fn len(&self) -> usize { match self { Enum::A(x) => x.len(), Enum::B(x) => x.len(), } } }

impl std::future::Future for Enum where A: std::future::Future, B: std::future::Future::Output>, { type Output = ::Output;

fn poll(
    self: std::pin::Pin<&mut Self>,
    cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
    unsafe {
        match self.get_unchecked_mut() {
            Enum::A(x) => std::pin::Pin::new_unchecked(x).poll(cx),
            Enum::B(x) => std::pin::Pin::new_unchecked(x).poll(cx),
        }
    }
}

} ```

Related Projects

License

Licensed under either of

at your option.

Contribution

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.