auto-concat-array 0.1.0

Concatenate fixed-size arrays on stable Rust with automatic array length inference.
Documentation
# auto-concat-array


Concatenate fixed-size arrays on **stable Rust** with automatic array length inference and zero unused compile-time overhead.

## Motivation


In current stable Rust, concatenating two arrays `[T; N]` and `[T; M]` to return an array of size `[T; N + M]` is not directly possible because the `#![feature(generic_const_exprs)]` feature is heavily unstable. 

While other crates solve this via process macros at the call site (which breaks natural type inference chaining) or complex `typenum` math, `auto-concat-array` takes a different approach: **Inversion of Control via Macros and Traits.**

It provides a `ConcatHelper` trait and an `impl_concat!` macro, allowing you to generate exactly the implementations you need for your own local marker types.

## Highlights


- **Seamless Type Inference**: Once wrapped in a generic function, you don't need to specify the output array's length. The compiler deduces `[T; N + M]` automatically. It feels exactly like native Rust.
- **Pay For What You Use**: Instead of pre-generating tens of thousands of combinations and severely bloating compilation times, *you* decide which length combinations matter to your project.
- **No Orphan Rule Conflicts**: By implementing the trait on your own custom marker struct, you avoid trait implementation collisions across the ecosystem.
- **Chainable**: Because it resolves at the type-system level rather than relying on AST-expanding macros at the call site, you can smoothly chain function calls (e.g., `concat(concat(a, b), c)`).

## Usage


Add this to your `Cargo.toml`:

```toml
[dependencies]
auto-concat-array = "0.1.0"
```

### Example


```rust
use auto_concat_array::{impl_concat, ConcatHelper};

// 1. Define your own local marker type
struct MyArrayTools;

// 2. Generate concatenations ONLY for what you need!
// You can generate specific large array combinations:
impl_concat!(MyArrayTools; (100, 200), (300, 100));

// Or generate a matrix of combinations using ranges (N in 0..16, M in 0..16):
impl_concat!(MyArrayTools; 0..16 ; 0..16);

// 3. Create a wrapper function for seamless type inference
fn array_concat<T, const N: usize, const M: usize>(
    a: [T; N],
    b: [T; M],
) -> <MyArrayTools as ConcatHelper<T, N, M>>::Output
where
    T: Copy,
    MyArrayTools: ConcatHelper<T, N, M>,
{
    MyArrayTools::do_concat(a, b)
}

fn main() {
    // Works perfectly with generated small array ranges
    let str_a = ["Rust", "is"];
    let str_b = ["Awesome", "!"];
    
    // The compiler knows `str_c` is exactly `[&str; 4]`!
    let str_c = array_concat(str_a, str_b);
    assert_eq!(str_c, ["Rust", "is", "Awesome", "!"]);

    // Works with your specifically hand-picked large combinations
    let large_a = [0; 100];
    let large_b = [1; 200];
    let large_c = array_concat(large_a, large_b);
    
    assert_eq!(large_c.len(), 300);
}
```

## Limitations


- **`T: Copy` Requirement**: Currently, the macro implementation uses array indexing and requires the elements to implement `Copy`.
- **Combinatorial Explosion Caution**: While `impl_concat!` accepts ranges like `0..256 ; 0..256`, doing so will generate `65,536` implementations for your struct. This *will* exponentially slow down the Rust compiler. Only generate the ranges you actively need (e.g., `0..16`, or `0..32`), and use specific tuples for larger buffers.
- **Not "Infinite"**: If you attempt to concatenate arrays whose lengths fall outside the bounds you generated with `impl_concat!`, you will receive a compile-time error: `trait bound not satisfied`.

## License


Dual-licensed under either of

* Apache License, Version 2.0
* MIT license

at your option.