use std::{fs, path::Path}; use derive_more::Deref; pub const XOR_LEN: usize = 8; #[derive(Debug, Clone, Copy, Deref, PartialEq, Eq)] pub struct XORBytes([u8; XOR_LEN]); impl XORBytes { /// All-zero mask: nodes without `xor.dat` need no decode. #[inline] pub fn is_identity(self) -> bool { self.0 == [0u8; XOR_LEN] } } impl From<[u8; XOR_LEN]> for XORBytes { #[inline] fn from(value: [u8; XOR_LEN]) -> Self { Self(value) } } impl From<&Path> for XORBytes { /// Loads `/xor.dat`. Falls back to the identity mask /// if missing, unreadable, or the wrong length. #[inline] fn from(value: &Path) -> Self { let mask = fs::read(value.join("xor.dat")) .ok() .and_then(|v| <[u8; XOR_LEN]>::try_from(v).ok()) .unwrap_or([0; XOR_LEN]); Self(mask) } }