mirror of
https://github.com/leonardomso/rust-skills.git
synced 2026-09-14 19:33:21 +08:00
5f0b2079f8
Add unsafe, concurrency, conversions, and pattern-matching categories plus rules across existing ones, and correct advice that was outdated for Rust 1.96.
2.5 KiB
2.5 KiB
conv-fromstr-parsing
Implement
FromStrto enablestr::parsefor string-to-type conversions
Why It Matters
FromStr is the single standard hook for parsing a &str into a typed value. Implementing it unlocks the idiomatic .parse::<T>() call, integrates with CLI argument parsers (clap, argh), and is the expected interface for serde string-deserializable types. A bespoke fn parse_foo(s: &str) forces callers to learn a private name and breaks generic code that constrains T: FromStr.
Bad
#[derive(Debug)]
enum Color { Red, Green, Blue }
// Callers must know this private name; no `.parse()` support
fn parse_color(s: &str) -> Result<Color, String> {
match s {
"red" => Ok(Color::Red),
"green" => Ok(Color::Green),
"blue" => Ok(Color::Blue),
other => Err(format!("unknown color: {other}")),
}
}
fn main() {
let c = parse_color("red").unwrap();
}
Good
use std::str::FromStr;
use std::fmt;
#[derive(Debug, PartialEq)]
enum Color { Red, Green, Blue }
#[derive(Debug)]
struct ParseColorError(String);
impl fmt::Display for ParseColorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "unknown color: {}", self.0)
}
}
impl std::error::Error for ParseColorError {}
impl FromStr for Color {
type Err = ParseColorError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"red" => Ok(Color::Red),
"green" => Ok(Color::Green),
"blue" => Ok(Color::Blue),
other => Err(ParseColorError(other.to_owned())),
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Standard idiom — works with clap, config parsers, etc.
let c: Color = "green".parse()?;
assert_eq!(c, Color::Green);
Ok(())
}
Notes
- Use a concrete
Errtype, notString, so callers can pattern-match on parse failures. FromStrpairs naturally withDisplay: if you can parse it in, you should be able to print it out.- For infallible string conversions (e.g., wrapping a
Stringin a newtype), considerFrom<&str>orFrom<String>instead. - CLI crates like
clapdetectFromStrautomatically via thevalue_parserattribute macro.
See Also
- conv-tryfrom-fallible -
TryFromfor fallible non-string conversions - type-newtype-validated - newtypes for validated data like
Email,Url - api-parse-dont-validate - parse into validated types at boundaries