5

I am trying to parse a particular string which has format similar to this:

prefix,body1:body2

I would like to use .chars method and other methods like .take_while and others like this:

let chars = str.chars();
let prefix: String = chars.take_while(|&c| c != ',').collect();
let body1: String = chars.take_while(|&c| c != ':').collect();
let body2: String = chars.take_while(|_| true).collect();

(Playground)

But the compiler complains:

error: use of moved value: `chars` [E0382]
     let body1: String = chars.take_while(|&c| c != ':').collect();
                         ^~~~~
help: see the detailed explanation for E0382
note: `chars` moved here because it has type `core::str::Chars<'_>`, which is non-copyable
     let prefix: String = chars.take_while(|&c| c != ',').collect();
                                  ^~~~~

I can rewrite it to a plain for loop and accumulate the value, but this is something I would like to avoid.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
franza
  • 2,297
  • 25
  • 39

1 Answers1

6

It's probably simplest to just split the string on the delimiters:

fn main() {
    let s = "prefix,body1:body2";
    let parts: Vec<_> = s.split(|c| c == ',' || c == ':').collect();
    println!("{:?}", parts);
}

However, if you want to use the iterators, you can avoid consuming the Chars iterator by taking a mutable reference to it with Iterator::by_ref:

let str = "prefix,body1:body2";
let mut chars = str.chars();
let prefix: String = chars.by_ref().take_while(|&c| c != ',').collect();
let body1: String = chars.by_ref().take_while(|&c| c != ':').collect();
let body2: String = chars.take_while(|_| true).collect();

For more info on by_ref, see:

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Nice! But personally, I always forget that there are methods like `by_ref`, `as_mut` and such which do all that Rust magic. – franza Feb 19 '16 at 20:02
  • 2
    @franza, also `take_while(|_| true)` is unnecessary, you can just as well call `collect()` directly. – Vladimir Matveev Feb 20 '16 at 06:22