לדלג לתוכן

1.10 - ממשק תוכנית ושגיאות הניתנים לבדיקה - פתרון

פתרון שימור סוג הכשל

נעטוף את שגיאת הגודל במצב מתאים של טיפוס שגיאה חיצוני. כך נשמר גם מקור הכשל וגם השלב שבו הוא התרחש.

הוסיפו לספרייה מההרצאה:

#[derive(Debug, PartialEq)]
pub enum ParseError {
    MissingSeparator,
    InvalidCount,
    InvalidWidth,
    Size(SizeError),
}

pub fn size_from_line(line: &str) -> Result<usize, ParseError> {
    let (count, width) = line.split_once(':')
        .ok_or(ParseError::MissingSeparator)?;
    let count = count.parse().map_err(|_| ParseError::InvalidCount)?;
    let width = width.parse().map_err(|_| ParseError::InvalidWidth)?;
    payload_size(count, width).map_err(ParseError::Size)
}

#[cfg(test)]
mod parse_tests {
    use super::*;

    #[test]
    fn parses_and_preserves_errors() {
        assert_eq!(size_from_line("10:8"), Ok(80));
        assert_eq!(size_from_line("108"), Err(ParseError::MissingSeparator));
        assert_eq!(size_from_line("-1:8"), Err(ParseError::InvalidCount));
        assert_eq!(size_from_line("1:0"), Err(ParseError::Size(SizeError::ZeroWidth)));
    }
}

בתוכנית הפקודה אפשר להתאים על ParseError ולנסח הודעה למשתמש, או להדפיס כרגע את תיאור Debug בגבול החיצוני. החזרת None לכל הכשלים הייתה מוחקת את ההבדל בין פורמט פגום לבין בקשה תקינה תחבירית שאינה עומדת במדיניות.

הדוגמה היא הרחבה של src/lib.rs מההרצאה, ולא קובץ עצמאי ללא ההגדרה של payload_size. ההבחנה הזאת חשובה כאשר מעתיקים קטע קוד: צריך לדעת באיזה מודול ובאיזה חוזה הוא משתלב.