pub(crate) const GRID_MAGIC: u32 = u32::from_le_bytes(*b"BRDG");
pub(crate) const CACHE_MAGIC: u32 = u32::from_le_bytes(*b"BRDC");
pub(crate) const ARCHIVE_MAGIC: u32 = u32::from_le_bytes(*b"BRDA");
pub(crate) const VDB_MAGIC: i64 = 0x5644_4220;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum FileKind {
Grid,
Cache,
Archive,
Vdb,
}
impl FileKind {
pub const HEAD: usize = 8;
pub fn of(head: &[u8]) -> Option<Self> {
let word = |n: usize| head.get(..n);
if word(8) == Some(&VDB_MAGIC.to_le_bytes()[..]) {
return Some(FileKind::Vdb);
}
let magic = u32::from_le_bytes(word(4)?.try_into().ok()?);
match magic {
GRID_MAGIC => Some(FileKind::Grid),
CACHE_MAGIC => Some(FileKind::Cache),
ARCHIVE_MAGIC => Some(FileKind::Archive),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn each_kind_is_told_by_its_magic_number_and_no_other_bytes_are() {
let cases: [(&[u8], Option<FileKind>); 9] = [
(b"BRDG\x02\0\0\0", Some(FileKind::Grid)),
(b"BRDC", Some(FileKind::Cache)),
(b"BRDAxyz", Some(FileKind::Archive)),
(&[0x20, 0x42, 0x44, 0x56, 0, 0, 0, 0], Some(FileKind::Vdb)),
(&[0x20, 0x42, 0x44, 0x56, 0, 0, 0, 1], None),
(&[0x20, 0x42, 0x44, 0x56], None),
(b"BRD", None),
(b"BRDX\0\0\0\0", None),
(b"", None),
];
for (head, kind) in cases {
assert_eq!(FileKind::of(head), kind, "{head:?}");
}
}
}