The collect's in the middle aren't necessary, neither is splitting by ": ". Here's a simpler version
fn main() {
let text = "seeds: 79 14 55 13\nwhatever";
let seeds: Vec<_> = text
.lines()
.next()
.unwrap()
.split_whitespace()
.skip(1)
.map(|x| x.parse::().unwrap())
.collect();
println!("seeds: {:?}", seeds);
}
It is simpler to bang out a [int(num) for num in text.splitlines()[0].split(' ')[1:]] in Python, but that just shows the happy path with no error handling, and does a bunch of allocations that the Rust version doesn't. You can also get slightly fancier in the Rust version by collecting into a Result for more succinct error handling if you'd like.
EDIT: Here's also a version using anyhow for error handling, and the aforementioned Result collecting:
use anyhow::{anyhow, Result};
fn main() -> Result<()> {
let text = "seeds: 79 14 55 13\nwhatever";
let seeds: Vec = text
.lines()
.next()
.ok_or(anyhow!("No first line!"))?
.split_whitespace()
.skip(1)
.map(str::parse)
.collect::>()?;
println!("seeds: {:?}", seeds);
Ok(())
}
Yeah I was trying to do something like reading the first line by getting an iterator and just looping through the other lines normally, since first line was kind of a special case but it got messy quick. I realized halfway that my collects were redundant but couldn't really simplify it. Thanks
Also, anyhow::Context provides a convenient way to turn Option<T> and Result<T, Into<anyhow::Error>> into anyhow::Result<T>
Like this:
use anyhow::Context;
// to my understanding it's better to
// specify the types when their names
// are the same as in prelude to improve
// readability and reduce name clashing
fn main() -> anyhow::Result<()> {
let text = "seeds: 79 14 55 13\nwhatever";
let seeds: Vec<u32> = text
.lines()
.next()
.context("No first line!")? // This line has changed
.split_whitespace()
.skip(1)
.map(str::parse)
.collect::<Result<_, _>>()?;
println!("seeds: {:?}", seeds);
Ok(())
}