macro-template 0.0.1

Macro to generate repeated Rust code with table-driven sources.
Documentation
# macro-template

[![Crates.io][crates-badge]][crates-url]
[![Documentation][docs-badge]][docs-url]
[![MSRV 1.85][msrv-badge]](https://www.whatrustisit.com)
[![Apache 2.0 licensed][license-badge]][license-url]
[![Build Status][actions-badge]][actions-url]

[crates-badge]: https://img.shields.io/crates/v/macro-template.svg
[crates-url]: https://crates.io/crates/macro-template
[docs-badge]: https://img.shields.io/docsrs/macro-template
[docs-url]: https://docs.rs/macro-template
[msrv-badge]: https://img.shields.io/badge/MSRV-1.85-green?logo=rust
[license-badge]: https://img.shields.io/crates/l/macro-template
[license-url]: LICENSE
[actions-badge]: https://github.com/fast/macro-template/workflows/CI/badge.svg
[actions-url]: https://github.com/fast/macro-template/actions?query=workflow%3ACI

## Overview

macro-template is a procedural macro that generates repeated Rust code in multiple places with table-driven sources.

For example, the following code generates `From` implementations for `MyEnum` from all its variants:

```rust
enum MyEnum {
    A(MyStructA),
    B(MyStructB),
    C(MyStructC),
}

macro_template::template! {
    for (Variant, Type) in [(A, MyStructA), (B, MyStructB), (C, MyStructC)] {
        impl From<Type> for MyEnum {
            fn from(value: Type) -> Self {
                MyEnum::Variant(value)
            }
        }
    }
}
```

You can iterate over a matrix as well:

```rust
macro_template::template! {
    for (Endian, Method) in [
        (LittleEndian, to_le_bytes),
        (BigEndian, to_be_bytes),
        (NativeEndian, to_ne_bytes)
    ],
    for (Ty, Width) in [
        (u16, 2),
        (u32, 4),
    ],
    {
        impl StoreBytes<Endian, Width> for Ty {
            fn store_bytes(&self) -> [u8; Width] {
                self.Method()
            }
        }
    }
}
```

Or, you can generate repeated match arms by pattern:

```rust
macro_template::template! {
    for T in [Int, Real, Double] {
        match Foo {
            @splice { EvalType::T => { panic!("{}", EvalType::T); }, }
            EvalType::Other => unreachable!(),
        }
    }
}
```

Naturally, if the match arm differs left-hand side and right-hand side:

```rust
macro_template::template! {
    for (K, Value) in [
        (Apple, "apple"),
        (Banana, "banana"),
        (Cherry, "cherry"),
    ] {
        match kind {
            @splice { Kind::K => { println!("{}", Value); }, }
        }
    }
}
```

The iterator can be a sequence of numbers, characters, or bytes:

```rust
// sequential numeric counter
let tuple = (1000, 100, 10);
let mut sum = 0;
macro_template::template! {
    for i in [0..3] {
        sum += tuple.i;
    }
}
assert_eq!(sum, 1110);

// sequential character collector
let mut string = String::new();
macro_template::template! {
    for c in ['x'..='z'] {
        string.push(c);
    }
}
assert_eq!(string, "xyz");
```

You can combine multiple iterators in a single template:

```rust
let mut values = Vec::new();

macro_template::template! {
    for Prefix in ["read", "write"],
    for Code in 200..=201 {
        values.push((Prefix, Code));
    }
}

assert_eq!(
    values,
    [("read", 200), ("read", 201), ("write", 200), ("write", 201)],
);
```

## Minimum Rust version policy

This crate's minimum supported `rustc` version is `1.85.0`.

The current policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if `crate 1.0` requires Rust 1.85.0, then `crate 1.0.z` for all values of `z` will also require Rust 1.85.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum version of Rust.

## License

This project is licensed under [Apache License, Version 2.0](LICENSE).

## Origins