Rust Parsing Strings
Parsing turns text into a value of another type. "42".parse() builds a value from text through the FromStr trait.
parse returns a Result
Use text.parse() to turn text into another type. It returns a Result, because the text might not fit the type:
let good: Result<i32, _> = "42".parse();
let bad: Result<i32, _> = "abc".parse();
println!("{:?} {:?}", good, bad);Name the target type two ways
Rust must know the target type. Write it as an annotation, or inside the call with the turbofish — the ::<...> part:
let a: i32 = "5".parse().unwrap();
let b = "10".parse::<i32>().unwrap();
println!("sum = {}", a + b);Numbers, bool and char all parse
parse works for any type that implements the FromStr trait. The standard library implements it for numbers, bool and char:
let flag: bool = "true".parse().unwrap();
let letter: char = "x".parse().unwrap();
println!("{} {}", flag, letter);Teach parse your own type
Implement FromStr for your type: name type Err, and write from_str. Inside, parse the pieces and return Ok, or pass an error out with ?:
impl FromStr for Age {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Age(s.trim().parse()?))
}
}Other bases use a different tool
Numbers written in other bases are not the job of parse. from_str_radix reads the base you name — the Parsing Numbers lesson goes deeper:
println!("{:?}", u32::from_str_radix("ff", 16));parse does not trim
Spaces are not skipped for you. This text fails, even though the number inside is fine:
println!("{:?}", " 42 ".parse::<i32>());Example
use std::num::ParseIntError;
use std::str::FromStr;
#[derive(Debug)]
struct Age(u8);
impl FromStr for Age {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let n: u8 = s.trim().parse()?;
Ok(Age(n))
}
}
fn main() {
let parsed: i32 = "5".parse().unwrap();
let turbo = "10".parse::<i32>().unwrap();
println!("sum = {}", parsed + turbo);
let flag: bool = "true".parse().unwrap();
println!("flag = {}", flag);
let age: Age = " 36 ".parse().unwrap();
println!("age = {}", age.0);
println!("bad = {:?}", "abc".parse::<i32>());
}Key points
- Going the other way is .to_string(): every Display type gets it for free — implement Display, never ToString by hand
- Some text has a specialist parser instead.
- A date string goes to one parser.
- It goes to chrono's NaiveDate::parse_from_str("22/10/2026", "%d/%m/%Y").
- A web address goes to the url crate.
- Url::parse hands back three things.
- It hands back the scheme.
- It hands back the host and query pairs.
- They are already split.
- Call .trim() first when spaces are allowed, as the User Input lesson did.
- Parsing reads text and builds a typed value from it.
In this example, Age teaches parse a skill. It teaches it how to build an Age from text. from_str trims the text. It parses it as a u8. It wraps it. In main, the first two lines show both ways. They show how to name the target type. One way is the annotation on parsed. The other is the turbofish on turbo. 5 + 10 prints sum = 15. A bool parses too, because the standard library implements FromStr for it. Then " 36 " becomes an Age. Our own impl does that. The last line shows failure staying calm. "abc" cannot be a number. So parse returns an Err. Nothing crashes.
Note
parse trims nothing by itself: " 42 ".parse::<i32>() fails with an invalid-digit error.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What must a type implement before "text".parse() can build a value of that type?