1.3 - ייצוג נתונים במבנים בטיפוסי סכום ובפרוסות - פתרון
פתרון פענוח בלי מצבים סותרים¶
נבדוק קודם שיש ארבעה בייטים. לאחר הבדיקה כל האינדקסים שבפונקציה מובטחים להיות בטווח, וההמרה למספר נעשית לפי סדר הבייטים של הפורמט.
#[derive(Debug, PartialEq)]
enum ParseResult {
Ready { kind: u8, length: u16 },
Short { missing: usize },
Unsupported { version: u8 },
}
fn parse(input: &[u8]) -> ParseResult {
if input.len() < 4 {
return ParseResult::Short { missing: 4 - input.len() };
}
if input[0] != 1 {
return ParseResult::Unsupported { version: input[0] };
}
ParseResult::Ready {
kind: input[1],
length: u16::from_le_bytes([input[2], input[3]]),
}
}
fn main() {
assert_eq!(parse(&[]), ParseResult::Short { missing: 4 });
assert_eq!(parse(&[1, 2, 3]), ParseResult::Short { missing: 1 });
assert_eq!(parse(&[2, 0, 0, 0]), ParseResult::Unsupported { version: 2 });
assert_eq!(parse(&[1, 7, 0x34, 0x12]), ParseResult::Ready { kind: 7, length: 0x1234 });
}
הפורמט החיצוני מוגדר בייט אחרי בייט, ואילו ה־enum הוא מודל פנימי של התוצאה. אין קשר מחייב בין הגודל והיישור שלו לבין ארבעת הבייטים של הכותרת. העתקה גולמית הייתה גם מתעלמת מן הצורך לבדוק שהייצוג יוצר ערך חוקי.
המצב Short אינו מחזיק סוג או אורך, משום שהם עדיין לא פוענחו. המצב Unsupported מחזיק רק את המידע שהצלחנו להבין לפי החוזה שלנו. כך לא ניתן לקרוא אורך שנראה תקף מתוך כותרת שבכלל לא התקבלה.