#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DATType {
Gearset = 0x006b0005,
GoldSaucer = 0x0067000A,
Hotbar = 0x00040002,
ItemFinder = 0x00CA0008,
ItemOrder = 0x00670007,
Keybind = 0x00650003,
LogFilter = 0x00030004,
Macro = 0x00020001,
RecentTells = 0x00640006,
UISave = 0x00010009,
Unknown = 0,
}
impl DATType {
pub const ACQ: DATType = DATType::RecentTells;
pub const GEARSET: DATType = DATType::Gearset;
pub const GS: DATType = DATType::GoldSaucer;
pub const ITEMFDR: DATType = DATType::ItemFinder;
pub const ITEMODR: DATType = DATType::ItemOrder;
pub const KEYBIND: DATType = DATType::Keybind;
pub const LOGFLTR: DATType = DATType::LogFilter;
pub const MACRO: DATType = DATType::Macro;
pub const MACROSYS: DATType = DATType::Macro;
pub const UISAVE: DATType = DATType::UISave;
}
impl From<u32> for DATType {
fn from(x: u32) -> DATType {
match x {
x if x == DATType::Gearset as u32 => DATType::Gearset,
x if x == DATType::GoldSaucer as u32 => DATType::GoldSaucer,
x if x == DATType::Hotbar as u32 => DATType::Hotbar,
x if x == DATType::ItemFinder as u32 => DATType::ItemFinder,
x if x == DATType::ItemOrder as u32 => DATType::ItemOrder,
x if x == DATType::Keybind as u32 => DATType::Keybind,
x if x == DATType::LogFilter as u32 => DATType::LogFilter,
x if x == DATType::Macro as u32 => DATType::Macro,
x if x == DATType::RecentTells as u32 => DATType::RecentTells,
x if x == DATType::UISave as u32 => DATType::UISave,
_ => DATType::Unknown,
}
}
}
pub fn get_mask_for_type(file_type: &DATType) -> Option<u8> {
match file_type {
DATType::Gearset
| DATType::GoldSaucer
| DATType::ItemFinder
| DATType::ItemOrder
| DATType::Keybind
| DATType::Macro
| DATType::RecentTells => Some(0x73),
DATType::Hotbar | DATType::UISave => Some(0x31),
DATType::LogFilter => Some(0x00),
_ => None,
}
}
pub fn get_default_end_byte_for_type(file_type: &DATType) -> Option<u8> {
match file_type {
DATType::Gearset
| DATType::GoldSaucer
| DATType::ItemFinder
| DATType::ItemOrder
| DATType::Keybind
| DATType::Macro
| DATType::RecentTells => Some(0xFF),
DATType::Hotbar => Some(0x31),
DATType::LogFilter => Some(0x00),
DATType::UISave => Some(0x21),
_ => None,
}
}
pub fn get_default_max_size_for_type(file_type: &DATType) -> Option<u32> {
match file_type {
DATType::Gearset => Some(44849),
DATType::GoldSaucer => Some(649),
DATType::Hotbar => Some(204800),
DATType::ItemFinder => Some(14030),
DATType::ItemOrder => Some(15193),
DATType::Keybind => Some(20480),
DATType::LogFilter => Some(2048),
DATType::Macro => Some(286720),
DATType::RecentTells => Some(2048),
DATType::UISave => Some(64512),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Read;
const FILE_TYPE_MAP: [(DATType, &str); 9] = [
(DATType::ACQ, "./resources/default_dats/ACQ.DAT"),
(DATType::GEARSET, "./resources/default_dats/GEARSET.DAT"),
(DATType::GS, "./resources/default_dats/GS.DAT"),
(DATType::ITEMFDR, "./resources/default_dats/ITEMFDR.DAT"),
(DATType::ITEMODR, "./resources/default_dats/ITEMODR.DAT"),
(DATType::KEYBIND, "./resources/default_dats/KEYBIND.DAT"),
(DATType::LOGFLTR, "./resources/default_dats/LOGFLTR.DAT"),
(DATType::MACRO, "./resources/default_dats/MACRO.DAT"),
(DATType::UISAVE, "./resources/default_dats/UISAVE.DAT"),
];
#[test]
fn test_from_header_bytes() -> Result<(), String> {
for case in FILE_TYPE_MAP.iter() {
let mut file = match File::open(case.1) {
Ok(file) => file,
Err(err) => return Err(format!("Error opening file: {}", err)),
};
let mut buf = [0u8; 4];
match file.read(&mut buf) {
Ok(_) => (),
Err(err) => return Err(format!("Error reading file: {}", err)),
};
let id_bytes = u32::from_le_bytes(buf);
assert_eq!(DATType::from(id_bytes), case.0);
}
Ok(())
}
#[test]
fn test_get_default_end_byte_for_type() -> Result<(), String> {
for case in FILE_TYPE_MAP.iter() {
match get_default_end_byte_for_type(&case.0) {
Some(_) => (),
None => return Err(format!("No value returned for case {}.", case.1)),
};
}
Ok(())
}
#[test]
fn test_get_default_max_size_for_type() -> Result<(), String> {
for case in FILE_TYPE_MAP.iter() {
match get_default_max_size_for_type(&case.0) {
Some(_) => (),
None => return Err(format!("No value returned for case {}.", case.1)),
};
}
Ok(())
}
#[test]
fn test_get_mask_for_type() -> Result<(), String> {
for case in FILE_TYPE_MAP.iter() {
match get_mask_for_type(&case.0) {
Some(_) => (),
None => return Err(format!("No value returned for case {}.", case.1)),
};
}
Ok(())
}
}