FromStr 을 구현하면 파싱을 공통적인 방법으로 수행할 수 있다고
- https://doc.rust-lang.org/std/str/trait.FromStr.html
예를 들어 우리가 "(1,2)"
를 제공하면 Point
객체를 알아서 파싱해서 리턴해주는 함수를 만든다고 가정하자.
struct Point { x: i32, y: i32, }
struct ParsePointError;
fn parse_to_point(s: &str) -> Result<Point, ParsePointError> {
// ...
}
뭐 이렇게 해도 세상이 멸망하는 정도는 아니지만 std 의 다양한 응용을 활용할 수 없다는 문제가 있다. 따라서 문자열로부터 객체를 파싱해야 할 일이 있을 땐 FromStr
트레이트를 구현하도록 하자.
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: i32 = x.parse().map_err(|_| ParsePointError)?;
let y_fromstr: i32 = y.parse().map_err(|_| ParsePointError)?;
Ok(Point {x: x_fromstr, y: y_fromstr})
}
}
사용할 수 있는 편의 함수들이 이젠 널리고 널렸다. 다음 코드를 보자
fn main() {
let expected = Ok(Point {x: 1, y: 2});
let fromstr = "(1,2)";
// Explicit call
assert_eq!(Point::from_str(&fromstr), expected);
// Implicit calls
assert_eq!(fromstr.parse(), expected);
assert_eq!(fromstr.parse::<Point>(), expected);