I'm learning Rust and I'd like advice on how to make my code more idiomatic. I have a set of entries that are colon separated string-number pairs, a name and a size, like so:
"foo:1234" " bar:943" "baz:666"
I want to split these into two variables, a String and a u64 which the code below does but it feels really ugly.
- There might be entries where one of the values is missing so I check for this by splitting the string into a vector so I can check the length. Is there a better way to do this?
- The fact that have a vector means that when I pop the values I have to deal with pop returning an Option that might be
None
. This is why there are match statements that assert if the value can't be found (a case that I don't think can occur because I know the length is 2). - The variables, name and size are mutable because I need to set them at declaration time or the compiler complains that only one of the paths through the match initializes them and they might be uninitialized when the prints display them. Can I mark the
None
case in some way to let the compiler know that the print is only reached through theSome
case?
As well as the above questions any suggestions for how to make this code more idiomatic would be much appreciated.
for data in entries { let mut split_data: Vec<String> = data.split(":").map(|s| s.to_string()).collect(); if split_data.len() == 2 { let mut size: u64 = 0; match split_data.pop() { Some(m) => {size = m.parse::<u64>().unwrap()}, None => {assert!(false, "error when reading size");}, } let mut name: String = "".to_string(); match split_data.pop() { Some(m) => {name = m.trim().to_string()}, None => {assert!(false, "error when reading name");}, } println!("name = {}", name); println!("size = {}", size); } }