Ce face FromStr
FromStr are o singură metodă, from_str, care transformă un &str în tipul tău sau returnează o eroare. Toate numerele, bool, char, IpAddr îl au deja. Odată implementat pentru tipul tău, poți folosi str::parse, care este forma obișnuită de apel.
Tipul erorii se alege cu type Err. Pentru programe mici un String cu mesajul ajunge; în biblioteci se folosește un tip de eroare propriu, cu Display.
Parametri
| Parametru | Descriere |
|---|---|
type Err |
Tipul erorii. |
from_str(s) |
Primește textul și returnează Result<Self, Self::Err>. |
Ce returnează
Result<Self, Self::Err>.
Exemple
Exemplul 1: O dată în format românesc
use std::str::FromStr;
#[derive(Debug)]
struct Data {
zi: u8,
luna: u8,
an: u16,
}
impl FromStr for Data {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parti: Vec<&str> = s.trim().split('.').collect();
let [zi, luna, an] = parti[..] else {
return Err(format!("„{s}” nu are forma zz.ll.aaaa"));
};
let zi: u8 = zi.parse().map_err(|_| format!("zi invalidă: {zi}"))?;
let luna: u8 = luna.parse().map_err(|_| format!("lună invalidă: {luna}"))?;
let an: u16 = an.parse().map_err(|_| format!("an invalid: {an}"))?;
if !(1..=31).contains(&zi) || !(1..=12).contains(&luna) {
return Err(format!("dată imposibilă: {s}"));
}
Ok(Data { zi, luna, an })
}
}
fn main() {
for t in ["19.10.2026", "1.12.1918", "31.13.2026", "2026-10-19", "aa.10.2026"] {
match t.parse::<Data>() {
Ok(d) => println!("{t}: anul {}, luna {}, ziua {}", d.an, d.luna, d.zi),
Err(e) => println!("{t}: eroare – {e}"),
}
}
}
Rezultat
19.10.2026: anul 2026, luna 10, ziua 19
1.12.1918: anul 1918, luna 12, ziua 1
31.13.2026: eroare – dată imposibilă: 31.13.2026
2026-10-19: eroare – „2026-10-19” nu are forma zz.ll.aaaa
aa.10.2026: eroare – zi invalidă: aa
Exemplul 2: Un enum citit din text
use std::str::FromStr;
#[derive(Debug, PartialEq)]
enum Culoare {
Rosu,
Galben,
Albastru,
}
impl FromStr for Culoare {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"roșu" | "rosu" => Ok(Culoare::Rosu),
"galben" => Ok(Culoare::Galben),
"albastru" => Ok(Culoare::Albastru),
_ => Err(format!("culoare necunoscută: {s}")),
}
}
}
fn main() {
let tricolor: Result<Vec<Culoare>, _> = "albastru galben ROȘU"
.split_whitespace()
.map(str::parse)
.collect();
println!("{tricolor:?}");
println!("{:?}", Culoare::from_str("verde"));
println!("{}", "galben".parse() == Ok(Culoare::Galben));
}
Rezultat
Ok([Albastru, Galben, Rosu])
Err("culoare necunoscută: verde")
true
Greșeli frecvente
- Scrii o funcție separată
fn din_text(s: &str)în loc deFromStr. Merge, dar pierziparse()și integrarea cu restul bibliotecii. - Uiți
use std::str::FromStr;când apelezi directCuloare::from_str. Pentruparse()importul nu este necesar.
Comenzi înrudite
str::parse: Transformă textul într-o altă valoare (număr, bool, char, IP, tip propriu) și returnează Result.TryFrom: Conversii care pot eșua și returnează Result: u8::try_from(300) dă Err. Implementarea aduce și try_into().From: Trait-ul pentru conversii care nu pot eșua: Tinta::from(x). Implementându-l, primești gratuit și x.into().ToString: Trait-ul metodei to_string(); există automat pentru orice tip cu Display, deci nu se implementează direct.