100 Exercises To Learn Rust - 5.6 Fallibility 풀기

문제

// TODO: `Ticket::new`를 panic 대신 `Result`를 리턴하도록 변환하세요.
// 에러 타입으로는 `String`을 사용합니다.

#[derive(Debug, PartialEq)]
struct Ticket {
    title: String,
    description: String,
    status: Status,
}

#[derive(Debug, PartialEq)]
enum Status {
    ToDo,
    InProgress { assigned_to: String },
    Done,
}

impl Ticket {
    pub fn new(title: String, description: String, status: Status) -> Ticket {
        if title.is_empty() {
            panic!("Title cannot be empty");
        }
        if title.len() > 50 {
            panic!("Title cannot be longer than 50 bytes");
        }
        if description.is_empty() {
            panic!("Description cannot be empty");
        }
        if description.len() > 500 {
            panic!("Description cannot be longer than 500 bytes");
        }

        Ticket {
            title,
            description,
            status,
        }
    }
}

 

풀이

impl Ticket {
    pub fn new(title: String, description: String, status: Status) -> Result<Ticket, String> {
        if title.is_empty() {
            return Err("Title cannot be empty".into());
        }
        if title.len() > 50 {
            return Err("Title cannot be longer than 50 bytes".into());
        }
        if description.is_empty() {
            return Err("Description cannot be empty".into());
        }
        if description.len() > 500 {
            return Err("Description cannot be longer than 500 bytes".into());
        }

        Ok(Ticket {
            title,
            description,
            status,
        })
    }
}

 

 

 

new()Result<T, E>를 반환하도록 바꾼다. TOk에 해당하므로 Ticket을, EErr에 해당하므로 문제에서 요구한대로 String을 사용한다.

 

문제가 없는 경우에는 Ok(Ticket{})을 반환하고, 각각의 케이스에서 문제가 발생하는 경우에는 Err()를 반환한다.

 

if문 내부에는 명시적으로 return 키워드를 작성해 모든 경로에서 반환값이 제공됨을 보장한다.