Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thomaseizinger/rust-impl-template
https://github.com/thomaseizinger/rust-impl-template
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/thomaseizinger/rust-impl-template
- Owner: thomaseizinger
- License: other
- Created: 2020-02-09T03:48:05.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2020-02-09T03:50:38.000Z (almost 5 years ago)
- Last Synced: 2024-12-16T20:05:57.946Z (about 1 month ago)
- Language: Rust
- Size: 15.6 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# 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 my_fn(_arg1: __TYPE0__, _arg2: __TYPE1__) -> __TYPE2__ {
unimplemented!()
}
}
```The above code expands to the following (non-exhaustive list):
```rust
impl GenericFoo for One {
fn my_fn(_arg1: Bar, _arg2: Alpha) -> One {
unimplemented!()
}
}impl GenericFoo for One {
fn my_fn(_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.