In some logic that constructs a Vec<T>, certain conditions may have to satisfy before some items be added at a certain position, or it may be necessary to use a for, extend an IntoIterator<T> or append another Vec<T> at a certain position. Currently once any of these logic is in place, vec! must be split. It might be more ergonomic if vec! can integrate these logic with some kind of syntactic sugar. The effect would probably be like this:
let mut v = Vec::new();
v.push(1);
if true {
v.push(2);
}
for n in 3..5 {
v.push(n);
}
v.append(&mut vec![6, 7, 8]);
v.extend([9, 10]);
if let Some(n) = Some(11) {
v.push(n);
}
v
is equivalent to
vec_ext![
1,
@if true {
2
},
@for i in 3..5 {
i
},
@append(&mut vec![6, 7, 8]),
@extend([9, 10]),
@iflet Some(n) = Some(11) {
n
},
]
The syntactic details need to be discussed further. Thanks to Rust's macro system, we can use ordinary macro_rules or proc macro to try to implement it, unlike other languages where literal is directly at the language syntax level. Even if the discussion results in it not being suitable for inclusion in std (which seems likely), it can be implemented in a separate crate for those who need it. I will try to write an implementation later. Originally posted in internals, but since it is unlikely to make it to std, perhaps it would be more appropriate to post it here.
There isn't need for anything like this. Everything you wrote already has a much nicer, uniform, concise equivalent in the iterator library: Playground
However, I sometimes use that pattern anyway, particularly with long multiline lists, because it just feels nicer to have everything in a list literal rather than breaking it up.
vec_ext![
1,
@if (true) {
2
},
@for (i in 3..5) {
i
},
@append(&mut vec![6, 7, 8]),
@extend([9, 10]),
@if let (Some(n) = Some(11)) {
n
},
]
It was actually written the same day the thread posted and basically meets my needs, and may be expanded later. Sorry for forgetting to give feedback earlier.