1#![warn(missing_docs)]
7#![warn(unsafe_code)]
8
9use time::{Date, Month, Time};
10
11pub fn parse_fat_time(dos_time: u16) -> Option<Time> {
34 let hours = ((dos_time >> 11) as u8) & 0x1F;
38 if hours > 23 {
39 return None;
40 }
41 let minutes = ((dos_time >> 5) as u8) & 0x3F;
42 if minutes > 59 {
43 return None;
44 }
45 let seconds = (dos_time & 0x1F) as u8;
46 if seconds > 29 {
47 return None;
48 }
49
50 let time = Time::from_hms(hours, minutes, seconds * 2);
51
52 match time {
53 Ok(t) => Some(t),
54 Err(e) => panic!("Couldn't parse time: {}", e),
55 }
56}
57
58pub fn parse_fat_date(dos_date: u16) -> Option<Date> {
82 if dos_date == 0 {
86 return None;
87 }
88
89 let year: i32 = ((dos_date >> 9) & 0x7F) as i32;
90 if !(0..=127).contains(&year) {
92 return None;
93 }
94
95 let year = year + 1980;
96
97 let month = (dos_date >> 5) & 0x0f;
98
99 let month = match month {
100 1 => Month::January,
101 2 => Month::February,
102 3 => Month::March,
103 4 => Month::April,
104 5 => Month::May,
105 6 => Month::June,
106 7 => Month::July,
107 8 => Month::August,
108 9 => Month::September,
109 10 => Month::October,
110 11 => Month::November,
111 12 => Month::December,
112 _ => return None,
113 };
114
115 let day = (dos_date & 0x1F) as u8;
116
117 if !(1..=31).contains(&day) {
120 return None;
121 }
122
123 let date = Date::from_calendar_date(year, month, day);
124
125 match date {
126 Ok(d) => Some(d),
127 Err(e) => panic!("Couldn't parse date: {}", e),
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn parse_fat_date_works() {
137 let date = parse_fat_date(0);
139 assert!(date.is_none());
140
141 let date = parse_fat_date(0b0000000000100001);
144
145 assert!(date.is_some());
146 assert_eq!(date.unwrap().year(), 1980);
147 assert_eq!(date.unwrap().month(), Month::January);
148 assert_eq!(date.unwrap().day(), 1);
149
150 let date = parse_fat_date(0b1111111110011111);
152
153 assert!(date.is_some());
154 assert_eq!(date.unwrap().year(), 2107);
155 assert_eq!(date.unwrap().month(), Month::December);
156 assert_eq!(date.unwrap().day(), 31);
157
158 let date = parse_fat_date(0b0000001000100001);
160
161 assert!(date.is_some());
162 assert_eq!(date.unwrap().year(), 1981);
163 assert_eq!(date.unwrap().month(), Month::January);
164 assert_eq!(date.unwrap().day(), 1);
165
166 let date = parse_fat_date(0b0000000000100000);
168 assert!(date.is_none());
169
170 let date = parse_fat_date(0b0000000000000001);
172 assert!(date.is_none());
173
174 let date = parse_fat_date(0b0000000110100001);
176 assert!(date.is_none());
177 }
178
179 #[test]
180 fn parse_fat_time_works() {
181 let time = parse_fat_time(0);
183 assert!(time.is_some());
184 assert_eq!(time.unwrap().hour(), 0);
185 assert_eq!(time.unwrap().minute(), 0);
186 assert_eq!(time.unwrap().second(), 0);
187
188 let time = parse_fat_time(0b1011111101111101);
190 assert!(time.is_some());
191 assert_eq!(time.unwrap().hour(), 23);
192 assert_eq!(time.unwrap().minute(), 59);
193 assert_eq!(time.unwrap().second(), 58);
194
195 let time = parse_fat_time(0b1011111101111110);
197 assert!(time.is_none());
198
199 let time = parse_fat_time(0b1011111110011101);
201 assert!(time.is_none());
202
203 let time = parse_fat_time(0b1100011101111101);
205 assert!(time.is_none());
206 }
207
208 #[test]
210 fn external_tests_pass() {
211 let date = parse_fat_date(0xFF9F);
212 assert!(date.is_some());
213 assert_eq!(date.unwrap().year(), 2107);
214 assert_eq!(date.unwrap().month(), Month::December);
215 assert_eq!(date.unwrap().day(), 31);
216
217 let date = parse_fat_date(0xBF7D);
219 assert!(date.is_some());
220 assert_eq!(date.unwrap().year(), 2075);
221 assert_eq!(date.unwrap().month(), Month::November);
222 assert_eq!(date.unwrap().day(), 29);
223
224 let time = parse_fat_time(0xBF7D);
225 assert!(time.is_some());
226 assert_eq!(time.unwrap().hour(), 23);
227 assert_eq!(time.unwrap().minute(), 59);
228 assert_eq!(time.unwrap().second(), 58);
229
230 let date = parse_fat_date(0xFF9F);
231 assert!(date.is_some());
232 assert_eq!(date.unwrap().year(), 2107);
233 assert_eq!(date.unwrap().month(), Month::December);
234 assert_eq!(date.unwrap().day(), 31);
235
236 let date = parse_fat_date(0x0021);
237 assert!(date.is_some());
238 assert_eq!(date.unwrap().year(), 1980);
239 assert_eq!(date.unwrap().month(), Month::January);
240 assert_eq!(date.unwrap().day(), 1);
241
242 let time = parse_fat_time(0x477D);
243 assert!(time.is_some());
244 assert_eq!(time.unwrap().hour(), 8);
245 assert_eq!(time.unwrap().minute(), 59);
246 assert_eq!(time.unwrap().second(), 58);
247 }
248}