Expand description
§For-loops over any iterable in a macro
This crate provides a seq!
macro to repeat a fragment of source code and
substitute into each repetition a value of your choosing,
drawn from an iterable RHAI expression.
This is mostly compatible with the seq-macro crate.
use super_seq_macro::seq;
fn main() {
let tuple = (1000, 100, 10);
let mut sum = 0;
// Expands to:
//
// sum += tuple.0;
// sum += tuple.1;
// sum += tuple.2;
//
// This cannot be written using an ordinary for-loop because elements of
// a tuple can only be accessed by their integer literal index, not by a
// variable.
seq!(N in 0..=2 {
sum += tuple.N;
});
assert_eq!(sum, 1110);
}
-
If the input tokens contain a section surrounded by
#(
…)*
then only that part is repeated. -
The numeric counter can be pasted onto the end of some prefix to form sequential identifiers.
use super_seq_macro::seq;
seq!(N in 64..=127 {
#[derive(Debug)]
enum Demo {
// Expands to Variant64, Variant65, ...
#(
Variant~N,
)*
}
});
fn main() {
assert_eq!("Variant99", format!("{:?}", Demo::Variant99));
}
- RHAI provides functional tools like
.filter()
and.map()
on arrays.
use super_seq_macro::seq;
seq!(A in 0..3 {#(
const WITHOUT_~A: [u32; 2] = seq!(B in (0..3).collect().filter(|x| x != A) {
[ #( B, )* ]
});
)*});
assert_eq!(WITHOUT_0, [1, 2]);
assert_eq!(WITHOUT_1, [0, 2]);
assert_eq!(WITHOUT_2, [0, 1]);
- Since the backtick character is not available, the syntax
$"..."$
is provided for string interpolation.
use super_seq_macro::seq;
seq!(P in (0x000..0x00F).collect()
.map(|x| x.to_hex().to_upper()) // Convert to uppercase hex
.map(|x| "000".sub_string($"${x}"$.len()) + $"${x}"$) // Pad on the left with zeros
{
// expands to structs Pin000, ..., Pin009, Pin00A, ..., Pin00F
struct Pin~P;
});
- If the input tokens contain a section surrounded by
#(
…)#
then that part is taken verbatim and not repeated. Markers such as#(
…)*
within that segment are ignored (this can be useful for nestingseq!
invocations.)