ut181a/
utils.rs

1use chrono::{NaiveDate, NaiveDateTime};
2
3use error::*;
4
5pub(crate) fn read_stringz(data: &[u8]) -> String {
6    let zestr: Vec<u8> = data.into_iter().cloned().take_while(|&b| b != 0).collect();
7    String::from_utf8_lossy(&zestr).into_owned()
8}
9
10/// Read `DateTime` from bytes.
11pub(crate) fn read_datetime(data: &[u8]) -> Result<NaiveDateTime> {
12    let year = 2000 + (i32::from(data[0]) & 0x3F);
13    let month = (u32::from(data[0]) >> 6) | ((u32::from(data[1]) & 0x03) << 2);
14    let day = u32::from(data[1] >> 2) & 0x1F;
15
16    let hour = (u32::from(data[1]) >> 7) | ((u32::from(data[2]) & 0x0F) << 1);
17    let minute = (u32::from(data[2]) >> 4) | ((u32::from(data[3]) & 0x03) << 4);
18    let second = u32::from(data[3]) >> 2;
19
20    match NaiveDate::from_ymd_opt(year, month, day) {
21        None => Err(ErrorKind::InvalidDateTime(year, month, day, hour, minute, second).into()),
22        Some(date) => match date.and_hms_opt(hour, minute, second) {
23            None => Err(ErrorKind::InvalidDateTime(year, month, day, hour, minute, second).into()),
24            Some(datetime) => Ok(datetime),
25        },
26    }
27}
28
29pub(crate) fn allowed_char(c: char) -> bool {
30    (c as u32) >= 0x20 && (c as u32) <= 0x7E
31}