Трейт FromStr

#![allow(unused)]
fn main() {
pub trait FromStr: Sized {
    type Err;

    // Обязательный метод
    fn from_str(s: &str) -> Result<Self, Self::Err>;
}
}

Парсинг значения из строки

Метод from_str трейта FromStr часто используется неявно через метод parse типа str. Примеры смотрите в документации к parse.

FromStr не имеет параметра времени жизни, поэтому можно парсить только типы, которые сами не содержат параметра времени жизни. Другими словами, можно распарсить i32 с помощью FromStr, но не &i32. Можно распарсить структуру, содержащую i32, но не ту, что содержит &i32.

Формат ввода и круговая конверсия (round-tripping)

Формат ввода, ожидаемый реализацией FromStr для типа, зависит от самого типа. Проверяйте документацию по конкретному типу для ознакомления с форматами ввода, которые он умеет парсить. Обратите внимание, что формат ввода реализации FromStr для типа может не обязательно принимать формат вывода его реализации Display. Даже если это так, реализация Display может не быть lossless (без потерь), поэтому круговая конверсия может потерять информацию.

Однако, если тип имеет lossless реализацию Display, вывод которой предназначен для удобного машинного парсинга, а не только для восприятия человеком, то тип может принимать тот же формат в FromStr, и это должно быть задокументировано. Наличие реализаций Display и FromStr, где результат Display нельзя распарсить с помощью FromStr, может удивить пользователей.

Примеры

Базовая реализация FromStr для примера типа Point:

#![allow(unused)]
fn main() {
use std::str::FromStr;

#[derive(Debug, PartialEq)]
struct Point {
    x: i32,
    y: i32
}

#[derive(Debug, PartialEq, Eq)]
struct ParsePointError;

impl FromStr for Point {
    type Err = ParsePointError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let (x, y) = s
            .strip_prefix('(')
            .and_then(|s| s.strip_suffix(')'))
            .and_then(|s| s.split_once(','))
            .ok_or(ParsePointError)?;

        let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?;
        let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?;

        Ok(Point { x: x_fromstr, y: y_fromstr })
    }
}

let expected = Ok(Point { x: 1, y: 2 });
// Явный вызов
assert_eq!(Point::from_str("(1,2)"), expected);
// Неявные вызовы через parse
assert_eq!("(1,2)".parse(), expected);
assert_eq!("(1,2)".parse::<Point>(), expected);
// Некорректная входная строка
assert!(Point::from_str("(1 2)").is_err());
}

Связанные типы (Обязательные)

type Err

Связанный тип ошибки, который может быть возвращен при парсинге.

Обязательные методы

fn from_str(s: &str) -> Result<Self, Self::Err>

Парсит строку s, чтобы вернуть значение этого типа.

Если парсинг успешен, возвращает значение внутри Ok, в противном случае, когда строка имеет неправильный формат, возвращает ошибку, специфичную для внутренней части Err. Тип ошибки специфичен для реализации трейта.

Примеры

Базовое использование с i32 — типом, который реализует FromStr:

#![allow(unused)]
fn main() {
use std::str::FromStr;

let s = "5";
let x = i32::from_str(s).unwrap();

assert_eq!(5, x);
}

Совместимость с dyn (динамической диспетчеризацией)

Этот трейт не совместим с dyn.

В более старых версиях Rust совместимость с dyn называлась "объектной безопасностью" (object safety), поэтому этот трейт не является объектно-безопасным.

Реализации (Implementors)

ТипНазначение (реализации FromStr)
IpAddrПарсинг IP-адреса (IPv4 или IPv6)
SocketAddrПарсинг сетевого адреса (IP + порт)
boolПарсинг логического значения ("true"/"false")
charПарсинг одного Unicode символа
f16Парсинг 16-битного числа с плавающей запятой
f32Парсинг 32-битного числа с плавающей запятой
f64Парсинг 64-битного числа с плавающей запятой
i8Парсинг 8-битного целого числа со знаком
i16Парсинг 16-битного целого числа со знаком
i32Парсинг 32-битного целого числа со знаком
i64Парсинг 64-битного целого числа со знаком
i128Парсинг 128-битного целого числа со знаком
isizeПарсинг целого числа со знаком размером с указатель
u8Парсинг 8-битного целого числа без знака
u16Парсинг 16-битного целого числа без знака
u32Парсинг 32-битного целого числа без знака
u64Парсинг 64-битного целого числа без знака
u128Парсинг 128-битного целого числа без знака
usizeПарсинг целого числа без знака размером с указатель
ByteStringПарсинг байтовой строки
CStringПарсинг строки, оканчивающейся нулем, для взаимодействия с C
OsStringПарсинг строки, специфичной для платформы
Ipv4AddrПарсинг IPv4 адреса
Ipv6AddrПарсинг IPv6 адреса
SocketAddrV4Парсинг IPv4 сетевого адреса (IPv4 + порт)
SocketAddrV6Парсинг IPv6 сетевого адреса (IPv6 + порт)
NonZero<i8>Парсинг гарантированно ненулевого i8
NonZero<i16>Парсинг гарантированно ненулевого i16
NonZero<i32>Парсинг гарантированно ненулевого i32
NonZero<i64>Парсинг гарантированно ненулевого i64
NonZero<i128>Парсинг гарантированно ненулевого i128
NonZero<isize>Парсинг гарантированно ненулевого isize
NonZero<u8>Парсинг гарантированно ненулевого u8
NonZero<u16>Парсинг гарантированно ненулевого u16
NonZero<u32>Парсинг гарантированно ненулевого u32
NonZero<u64>Парсинг гарантированно ненулевого u64
NonZero<u128>Парсинг гарантированно ненулевого u128
NonZero<usize>Парсинг гарантированно ненулевого usize
PathBufПарсинг пути в файловой системе
StringПарсинг строки (фактически создание String из &str)
LiteralПарсинг токена литерала (в контексте макросов/proc-macro)
TokenStreamПарсинг потока токенов (в контексте макросов/proc-macro)