wow_vanilla_dbc/tables/
pet_loyalty.rs1use crate::header::{HEADER_SIZE, DbcHeader};
2use crate::header;
3use crate::DbcTable;
4use std::io::Write;
5use crate::Indexable;
6use crate::LocalizedString;
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct PetLoyalty {
10 pub rows: Vec<PetLoyaltyRow>,
11}
12
13impl DbcTable for PetLoyalty {
14 type Row = PetLoyaltyRow;
15
16 fn filename() -> &'static str { "PetLoyalty.dbc" }
17
18 fn rows(&self) -> &[Self::Row] { &self.rows }
19 fn rows_mut(&mut self) -> &mut [Self::Row] { &mut self.rows }
20
21 fn read(b: &mut impl std::io::Read) -> Result<Self, crate::DbcError> {
22 let mut header = [0_u8; HEADER_SIZE];
23 b.read_exact(&mut header)?;
24 let header = header::parse_header(&header)?;
25
26 if header.record_size != 40 {
27 return Err(crate::DbcError::InvalidHeader(
28 crate::InvalidHeaderError::RecordSize {
29 expected: 40,
30 actual: header.record_size,
31 },
32 ));
33 }
34
35 if header.field_count != 10 {
36 return Err(crate::DbcError::InvalidHeader(
37 crate::InvalidHeaderError::FieldCount {
38 expected: 40,
39 actual: header.field_count,
40 },
41 ));
42 }
43
44 let mut r = vec![0_u8; (header.record_count * header.record_size) as usize];
45 b.read_exact(&mut r)?;
46 let mut string_block = vec![0_u8; header.string_block_size as usize];
47 b.read_exact(&mut string_block)?;
48
49 let mut rows = Vec::with_capacity(header.record_count as usize);
50
51 for mut chunk in r.chunks(header.record_size as usize) {
52 let chunk = &mut chunk;
53
54 let id = PetLoyaltyKey::new(crate::util::read_u32_le(chunk)?);
56
57 let name = crate::util::read_localized_string(chunk, &string_block)?;
59
60
61 rows.push(PetLoyaltyRow {
62 id,
63 name,
64 });
65 }
66
67 Ok(PetLoyalty { rows, })
68 }
69
70 fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
71 let header = DbcHeader {
72 record_count: self.rows.len() as u32,
73 field_count: 10,
74 record_size: 40,
75 string_block_size: self.string_block_size(),
76 };
77
78 b.write_all(&header.write_header())?;
79
80 let mut string_index = 1;
81 for row in &self.rows {
82 b.write_all(&row.id.id.to_le_bytes())?;
84
85 b.write_all(&row.name.string_indices_as_array(&mut string_index))?;
87
88 }
89
90 self.write_string_block(b)?;
91
92 Ok(())
93 }
94
95}
96
97impl Indexable for PetLoyalty {
98 type PrimaryKey = PetLoyaltyKey;
99 fn get(&self, key: &Self::PrimaryKey) -> Option<&Self::Row> {
100 self.rows.iter().find(|a| a.id.id == key.id)
101 }
102
103 fn get_mut(&mut self, key: &Self::PrimaryKey) -> Option<&mut Self::Row> {
104 self.rows.iter_mut().find(|a| a.id.id == key.id)
105 }
106
107}
108
109impl PetLoyalty {
110 fn write_string_block(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
111 b.write_all(&[0])?;
112
113 for row in &self.rows {
114 row.name.string_block_as_array(b)?;
115 }
116
117 Ok(())
118 }
119
120 fn string_block_size(&self) -> u32 {
121 let mut sum = 1;
122 for row in &self.rows {
123 sum += row.name.string_block_size();
124 }
125
126 sum as u32
127 }
128
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
132pub struct PetLoyaltyKey {
133 pub id: u32
134}
135
136impl PetLoyaltyKey {
137 pub const fn new(id: u32) -> Self {
138 Self { id }
139 }
140
141}
142
143#[derive(Debug, Clone, PartialEq)]
144pub struct PetLoyaltyRow {
145 pub id: PetLoyaltyKey,
146 pub name: LocalizedString,
147}
148