Crate ext_format

Source
Expand description

§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:

[dependencies]
ext_format = "0.1.0"

§Usage

§Basic Interpolation

Use $ for basic interpolation:

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.

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)
let numbers = vec![1, 2, 3];
let output = ext_format!("Numbers: $($numbers),*");
// Output: "Numbers: 1, 2, 3"

For using newlines as separators:

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.

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

§Repetition with named Iteration Variables

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

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:

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.

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:

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:

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 file for details.

Macros§

ext_format
ext_format_unindented