impl-template

impl-template is a procedural macro for the Rust programming language that allows you to define templates for "impl"-items and have them expanded to several instances depending on the configuration.

In a way, you can think of it as compile-time blanket impls if you know all types you want to implement it for upfront.

Usage

```rust trait Foo {}

struct Bar; struct Baz;

[impl_template]

impl Foo for ((Bar, Baz)) {

} ```

This will generate the following code:

```rust impl Foo for Bar {

}

impl Foo for Baz {

} ```

Advanced usage

impl-template looks for patterns of double tuples. Those are syntactically valid Rust code but AFAIK fairly useless and should thus not appear in day-to-day Rust-code.

Several double tuple patterns

You can have as many of those double-tuples as you want. impl-template will create a cartesian product out of all of them and generate the impl-blocks accordingly.

```rust trait GenericFoo { }

struct Bar; struct Baz;

struct One; struct Two; struct Three;

struct Alpha; struct Beta;

[impl_template]

impl GenericFoo<((Bar, Baz)), ((Alpha, Beta))> for ((One, Two, Three)) { } ``` The above snippet will expand to 12 impl blocks (2 * 3 * 2).

Referring to types

impl-template allows you to refer to types within the template block. It generates a dummy identifier for every double-tuple in the scheme of __TYPE{}__ with {} being replaced with a 0-based index.

We can extend GenericFoo with a method where we have to name the type parameters:

```rust trait GenericFoo { fn my_fn(arg1: T, arg2: S) -> Self; }

struct Bar; struct Baz;

struct One; struct Two; struct Three;

struct Alpha; struct Beta;

[impl_template]

impl GenericFoo<((Bar, Baz)), ((Alpha, Beta))> for ((One, Two, Three)) { fn myfn(arg1: TYPE0, _arg2: TYPE1) -> TYPE2 { unimplemented!() } } ```

The above code expands to the following (non-exhaustive list):

```rust impl GenericFoo for One { fn myfn(arg1: Bar, _arg2: Alpha) -> One { unimplemented!() } }

impl GenericFoo for One { fn myfn(arg1: Bar, _arg2: Beta) -> One { unimplemented!() } } ```

In other words, __TYPE0__ is an iterator-like placeholder for the first double-tuple ((Bar, Baz)), __TYPE1__ for the second one, etc.