ext_format 0.1.1

A small, yet powerful, Rust crate for string interpolation
Documentation
# ext_format

A small, yet powerful, Rust crate for string interpolation. Inspired by Rust's macro rules, it provides two main macros: `ext_format!` and `ext_format_unindent!` \
The `ext_format_unindent!` macro works exactly like `ext_format!`, but first trims leading whitespace, to make working with multiline strings less painful.

## Installation

Add the following to your `Cargo.toml`:

```toml
[dependencies]
ext_format = "0.1.0"
```

## Usage

### Basic Interpolation

Use `$` for basic interpolation:

```rust
let name = "Alice";
let output = ext_format!("Hello, $name!");
```

### Binding new variable names
Use `{name:new_name}` to bind a new name to a variable.

```rust
let number = 42;
let output = ext_format!("Number: ${number:n} $n $n");
// Output: "Number: 42 42 42"
```


### Basic Repetition

- `$($var)*`: No separators
- `$($var),*`: Character as a separator
- `$($var)(...)*`: String as a separator (supports escaped characters)

```rust
let numbers = vec![1, 2, 3];
let output = ext_format!("Numbers: $($numbers),*");
// Output: "Numbers: 1, 2, 3"
```

For using newlines as separators:

```rust
let items = vec!["apple", "banana", "cherry"];
let output = ext_format!("Items:\n$($items)(\n)*");
// Output:
// Items:
// apple
// banana
// cherry
```

### Repetition with Hidden Variables

Use `@` to include variables that control the loop but aren't included in the output.

```rust
let items = vec!["apple", "banana"];
let counter = vec![1, 2];
let output = ext_format!("Items:\n$(@counter)$($items)\n)*");
// Output:
// Items:
// apple
// banana
```

### Repetition with named Iteration Variables

Use `{name:new_name}` to bind a Name to a Variable.

```rust
let numbers = vec![1, 2, 3];
let output = ext_format!("Numbers: $(${numbers:number} $number),*");
// Output: "Numbers: 1 1, 2 2, 3 3"
```

### Nested Repetitions

Repetitions can contain other repetitions, acting like nested for-loops:

```rust
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let output = ext_format!("Matrix:\n$(@{matrix:row}$($row) *)(\n)*");
// Output:
// Matrix:
// 1 2 3
// 4 5 6
// 7 8 9
```

### Zipped Variables

Variables in a single repetition layer are automatically zipped together, meaning they iterate in lockstep.

```rust
let names = vec!["Alice", "Bob"];
let ages = vec![30, 40];
let output = ext_format!("Profiles:\n$($names $ages)\n)*");
// Profiles:
// Alice 30
// Bob 40
```

### Multiline Strings

For multiline strings, `ext_format_unindented` can be used to avoid leading whitespace:

```rust
fn unindented() -> String {
    let matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    ext_format_unindented!(r#"
        void func3() {
            $(@{matrix:inner_matrix}printf("$($inner_matrix) *");)(\n    )*
        }
    "#)
}
let output = unindented();
// Output:
// void func3() {
//     printf("1 2 3");
//     printf("4 5 6");
//     printf("7 8 9");
// }
```

If the regular `ext_format` was used here, it would result in the following:
```rust
fn indented() -> String {
    let matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    ext_format!(r#"
        void func3() {
            $(@{matrix:inner_matrix}printf("$($inner_matrix) *");)(\n                    )*
        }
    "#)
}
let output = indented();
// Output:
//                void func3() {
//                    printf("1 2 3");
//                    printf("4 5 6");
//                    printf("7 8 9");
//                }
```
With the indentation of the resulting string depending on the indentation of the function itself.

## License

This project is licensed under the MIT License. See the [LICENSE.md](LICENSE.md) file for details.