use binrw::{BinRead, BinWrite};
#[derive(Debug, Clone, Default, BinRead, BinWrite)]
#[brw(little)]
pub struct McrdChunk {
#[br(parse_with = binrw::helpers::until_eof)]
pub doodad_refs: Vec<u32>,
}
impl McrdChunk {
#[must_use]
pub fn count(&self) -> usize {
self.doodad_refs.len()
}
#[must_use]
pub fn contains_doodad(&self, mddf_index: u32) -> bool {
self.doodad_refs.contains(&mddf_index)
}
#[must_use]
pub fn validate_refs(&self, mddf_count: usize) -> bool {
self.doodad_refs
.iter()
.all(|&idx| (idx as usize) < mddf_count)
}
}
#[cfg(test)]
mod tests {
use super::*;
use binrw::{BinReaderExt, BinWriterExt};
use std::io::Cursor;
#[test]
fn test_mcrd_parse() {
let data = vec![
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, ];
let mut cursor = Cursor::new(data);
let mcrd: McrdChunk = cursor.read_le().unwrap();
assert_eq!(mcrd.count(), 5);
assert_eq!(mcrd.doodad_refs[0], 0);
assert_eq!(mcrd.doodad_refs[1], 5);
assert_eq!(mcrd.doodad_refs[2], 10);
assert_eq!(mcrd.doodad_refs[3], 20);
assert_eq!(mcrd.doodad_refs[4], 50);
}
#[test]
fn test_mcrd_empty() {
let data = vec![];
let mut cursor = Cursor::new(data);
let mcrd: McrdChunk = cursor.read_le().unwrap();
assert_eq!(mcrd.count(), 0);
assert!(mcrd.doodad_refs.is_empty());
}
#[test]
fn test_mcrd_round_trip() {
let original = McrdChunk {
doodad_refs: vec![1, 2, 3, 5, 8, 13, 21],
};
let mut buffer = Cursor::new(Vec::new());
buffer.write_le(&original).unwrap();
assert_eq!(buffer.position(), 28);
let data = buffer.into_inner();
let mut cursor = Cursor::new(data);
let parsed: McrdChunk = cursor.read_le().unwrap();
assert_eq!(original.doodad_refs, parsed.doodad_refs);
}
#[test]
fn test_mcrd_contains_doodad() {
let mcrd = McrdChunk {
doodad_refs: vec![10, 20, 30, 40],
};
assert!(mcrd.contains_doodad(10));
assert!(mcrd.contains_doodad(30));
assert!(!mcrd.contains_doodad(15));
assert!(!mcrd.contains_doodad(50));
}
#[test]
fn test_mcrd_validate_refs() {
let mcrd = McrdChunk {
doodad_refs: vec![0, 5, 10, 15],
};
assert!(mcrd.validate_refs(20));
assert!(!mcrd.validate_refs(15));
assert!(!mcrd.validate_refs(0));
}
#[test]
fn test_mcrd_default() {
let mcrd = McrdChunk::default();
assert_eq!(mcrd.count(), 0);
assert!(mcrd.doodad_refs.is_empty());
}
#[test]
fn test_mcrd_single_ref() {
let data = vec![0x2A, 0x00, 0x00, 0x00]; let mut cursor = Cursor::new(data);
let mcrd: McrdChunk = cursor.read_le().unwrap();
assert_eq!(mcrd.count(), 1);
assert_eq!(mcrd.doodad_refs[0], 42);
}
#[test]
fn test_mcrd_large_indices() {
let mcrd = McrdChunk {
doodad_refs: vec![1000, 5000, 10000],
};
let mut buffer = Cursor::new(Vec::new());
buffer.write_le(&mcrd).unwrap();
let data = buffer.into_inner();
let mut cursor = Cursor::new(data);
let parsed: McrdChunk = cursor.read_le().unwrap();
assert_eq!(parsed.doodad_refs[0], 1000);
assert_eq!(parsed.doodad_refs[1], 5000);
assert_eq!(parsed.doodad_refs[2], 10000);
}
}