1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
//! # 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
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format;
//! let numbers = vec![1, 2, 3];
//! let output = ext_format!("Numbers: $($numbers),*");
//! // Output: "Numbers: 1, 2, 3"
//! ```
//!
//! For using newlines as separators:
//!
//! ```rust
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format;
//! let items = vec!["apple", "banana", "cherry"];
//! let counter = vec![1, 2];
//! let output = ext_format!("Items:\n$(@counter $items)\n*");
//! // Output:
//! // Items:
//! // apple
//! // banana
//! ```
//! ```rust
//! # use ext_format::ext_format;
//! 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.
//!
//! ```rust
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format;
//! 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
//! # use ext_format::ext_format_unindented;
//! 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
//! # use ext_format::ext_format;
//! 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.
extern crate core;
use ;
use crategenerate_code;
use crateparse;
use crate;