Conditional iterator .chain()
⚓ Rust 📅 2025-07-29 👤 surdeus 👁️ 12You know how it works: I have some code that does what it is supposed to do but I don't like looking at it... ![]()
While processing a string I need to count a certain number of characters backward, and stop when some specific condition is reached. Then I process the string (except what I took from the end) but I may need the last character popped. .once() to the rescue but I can't use it in a single branch of an if because of the different type in the other branch. Right now I just "append" a fake character and then skip it while processing the string but... ![]()
Example code below and also on playground.
use std::iter::once;
fn main() {
let s = "abcdexxx";
// We have some logic here that both shortens `s` from the end and counts
// the occurences of some characters. When we know we need to stop it is
// too late and the first usefull character has already been popped. We
// place it in `e`.
let mut i = s.chars();
let e = loop {
// Logic is a bit more complex here, but this should suffice.
if let Some(c) = i.next_back() {
if c == 'a' {
break None;
}
if c != 'x' {
break Some(c);
}
}
else {
break None;
}
};
let s_iter = if let Some(e) = e {
s.chars().chain(once(e))
}
else {
// Comment the .chain() to make the compiler angry.
s.chars().chain(once('\0'))
};
for c in s_iter {
if c == '\0' {
continue;
}
// Process `c` here.
}
}
4 posts - 3 participants
🏷️ Rust_feed