I want to produce an iterator over a delimited string such that each substring separated by the delimiter is returned on each iteration with the substring from the previous iteration, including the delimiter.
For example, given the string "ab:cde:fg", the iterator should return the following:
"ab""ab:cde""ab:cde:fg"
Simple Solution
A simple solution is to just iterate over collection returned from splitting on the delimiter, keeping track of the previous path:
let mut state = String::new();
for part in "ab:cde:fg".split(':') {
if !state.is_empty() {
state.push_str(":");
}
state.push_str(part);
dbg!(&state);
}
The downside here is the need to explicitly keep track of the state with an extra mutable variable.
Using scan
I thought scan could be used to hide the state:
"ab:cde:fg"
.split(":")
.scan(String::new(), |state, x| {
if !state.is_empty() {
state.push_str(":");
}
state.push_str(x);
Some(&state)
})
.for_each(|x| { dbg!(x); });
However, this fails with the error:
cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
What is the problem with the scan version and how can it be fixed?