auto_impl 0.1.0

Automatically implement traits for common smart pointers and closures
Documentation
# `auto_impl` [![Build Status]https://travis-ci.org/KodrAus/auto_impl.svg?branch=master]https://travis-ci.org/KodrAus/auto_impl

A simple compiler plugin for automatically implementing a trait for some common smart pointers and closures.

# Usage

This library requires the `nightly` channel.

Add `auto_impl` to your `Cargo.toml`:

```
auto_impl = "*"
```

Reference in your crate root:

```rust
#![feature(proc_macro)]

extern crate auto_impl;

use auto_impl::auto_impl;
```

The following types are supported:

- [`Arc`]https://doc.rust-lang.org/std/sync/struct.Arc.html
- [`Rc`]https://doc.rust-lang.org/std/rc/struct.Rc.html
- [`Box`]https://doc.rust-lang.org/std/boxed/struct.Box.html
- [`Fn`]https://doc.rust-lang.org/std/ops/trait.Fn.html
- [`FnMut`]https://doc.rust-lang.org/std/ops/trait.FnMut.html
- [`FnOnce`]https://doc.rust-lang.org/std/ops/trait.FnOnce.html

## Implement a trait for a smart pointer

Add the `#[auto_impl]` attribute to traits to automatically implement them for wrapper types:

```rust
#[auto_impl(Arc, Box, Rc)]
trait MyTrait<'a, T> 
    where T: AsRef<str>
{
    type Type1;
    type Type2;

    fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String>;
    fn execute2(&self) -> Self::Type2;
}
```

Will expand to:

```rust
impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::sync::Arc<TAutoImpl>
    where TAutoImpl: MyTrait<'a, T>,
          T: AsRef<str>
{
    type Type1 = TAutoImpl::Type1;
    type Type2 = TAutoImpl::Type2;

    fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
        self.as_ref().execute1(arg1)
    }

    fn execute2(&self) -> Self::Type2 {
        self.as_ref().execute2()
    }
}

impl<'a, T, TAutoImpl> MyTrait<'a, T> for Box<TAutoImpl>
    where TAutoImpl: MyTrait<'a, T>,
          T: AsRef<str>
{
    type Type1 = TAutoImpl::Type1;
    type Type2 = TAutoImpl::Type2;

    fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
        self.as_ref().execute1(arg1)
    }

    fn execute2(&self) -> Self::Type2 {
        self.as_ref().execute2()
    }
}

impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::rc::Rc<TAutoImpl>
    where TAutoImpl: MyTrait<'a, T>,
          T: AsRef<str>
{
    type Type1 = TAutoImpl::Type1;
    type Type2 = TAutoImpl::Type2;

    fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
        self.as_ref().execute1(arg1)
    }

    fn execute2(&self) -> Self::Type2 {
        self.as_ref().execute2()
    }
}
```

There are a few restrictions on `#[auto_impl]` for smart pointers. The trait must:

- Only have methods that take `&self`

## Implement a trait for a closure

```rust
trait FnTrait2<'a, T> {
    fn execute<'b>(&'a self, arg1: &'b T, arg2: &'static str) -> Result<(), String>;
}
```

Will expand to:

```rust
impl<'a, T, TFn> FnTrait2<'a, T> for TFn
    where TFn: Fn(&T, &'static str) -> Result<(), String>
{
    fn execute<'b>(&'a self, arg1: &'b T, arg1: &'static str) -> Result<(), String> {
        self(arg1, arg2)
    }
}
```

There are a few restrictions on `#[auto_impl]` for closures. The trait must:

- Have a single method
- Have no associated types
- Have no non-static lifetimes in the return type