1use std::fmt::Debug;
2
3use byteorder::{LittleEndian, ReadBytesExt};
4pub use hash40::Hash40;
5use indexmap::IndexMap;
6use serde::Deserialize;
7
8use crate::de::{ReferenceData, ValueDeserializer};
9pub mod de;
10pub mod ser;
11
12pub use ser::to_vec;
13
14#[cfg(test)]
15mod tests;
16
17macro_rules! decl_id {
18 ($($name:ident => ($value:expr, $t:path)),*) => {
19 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
20 #[repr(u8)]
21 pub enum ParamId {
22 $($name = $value,)*
23 }
24
25 #[derive(Clone, PartialEq)]
26 pub enum Value {
27 $(
28 $name($t),
29 )*
30 }
31
32 $(
33 impl From<$t> for Value {
34 fn from(value: $t) -> Self {
35 Self::$name(value)
36 }
37 }
38 )*
39
40
41 impl TryFrom<u8> for ParamId {
42 type Error = u8;
43
44 fn try_from(value: u8) -> Result<Self, Self::Error> {
45 match value {
46 $(
47 $value => Ok(Self::$name),
48 )*
49 other => Err(other)
50 }
51 }
52 }
53
54 impl From<ParamId> for u8 {
55 fn from(value: ParamId) -> Self {
56 value as u8
57 }
58 }
59 }
60}
61
62impl Debug for Value {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 Self::Bool(v) => Debug::fmt(v, f),
66 Self::I8(v) => Debug::fmt(v, f),
67 Self::U8(v) => Debug::fmt(v, f),
68 Self::I16(v) => Debug::fmt(v, f),
69 Self::U16(v) => Debug::fmt(v, f),
70 Self::I32(v) => Debug::fmt(v, f),
71 Self::U32(v) => Debug::fmt(v, f),
72 Self::F32(v) => Debug::fmt(v, f),
73 Self::Hash(v) => write!(f, "{v}"),
74 Self::String(v) => Debug::fmt(v, f),
75 Self::List(v) => Debug::fmt(v, f),
76 Self::Map(v) => {
77 let mut map = f.debug_map();
78 for (k, v) in v.iter() {
79 map.key(&format!("{k}"));
80 map.value(v);
81 }
82 map.finish()
83 }
84 }
85 }
86}
87
88decl_id! {
89 Bool => (1, bool),
90 I8 => (2, i8),
91 U8 => (3, u8),
92 I16 => (4, i16),
93 U16 => (5, u16),
94 I32 => (6, i32),
95 U32 => (7, u32),
96 F32 => (8, f32),
97 Hash => (9, Hash40),
98 String => (10, String),
99 List => (11, Vec<Value>),
100 Map => (12, IndexMap<Hash40, Value>)
101}
102
103impl Value {
104 pub fn as_bool(&self) -> Option<bool> {
105 match self {
106 Self::Bool(b) => Some(*b),
107 _ => None,
108 }
109 }
110
111 pub fn as_i8(&self) -> Option<i8> {
112 match self {
113 Self::I8(v) => Some(*v),
114 Self::U8(v) => (*v).try_into().ok(),
115 Self::I16(v) => (*v).try_into().ok(),
116 Self::U16(v) => (*v).try_into().ok(),
117 Self::I32(v) => (*v).try_into().ok(),
118 Self::U32(v) => (*v).try_into().ok(),
119 _ => None,
120 }
121 }
122
123 pub fn as_u8(&self) -> Option<u8> {
124 match self {
125 Self::U8(v) => Some(*v),
126 Self::I8(v) => (*v).try_into().ok(),
127 Self::I16(v) => (*v).try_into().ok(),
128 Self::U16(v) => (*v).try_into().ok(),
129 Self::I32(v) => (*v).try_into().ok(),
130 Self::U32(v) => (*v).try_into().ok(),
131 _ => None,
132 }
133 }
134
135 pub fn as_i16(&self) -> Option<i16> {
136 match self {
137 Self::I8(v) => Some(*v as i16),
138 Self::U8(v) => Some(*v as i16),
139 Self::I16(v) => Some(*v),
140 Self::U16(v) => (*v).try_into().ok(),
141 Self::I32(v) => (*v).try_into().ok(),
142 Self::U32(v) => (*v).try_into().ok(),
143 _ => None,
144 }
145 }
146
147 pub fn as_u16(&self) -> Option<u16> {
148 match self {
149 Self::I8(v) => Some(*v as u16),
150 Self::U8(v) => Some(*v as u16),
151 Self::U16(v) => Some(*v),
152 Self::I16(v) => (*v).try_into().ok(),
153 Self::I32(v) => (*v).try_into().ok(),
154 Self::U32(v) => (*v).try_into().ok(),
155 _ => None,
156 }
157 }
158
159 pub fn as_i32(&self) -> Option<i32> {
160 match self {
161 Self::I8(v) => Some(*v as i32),
162 Self::U8(v) => Some(*v as i32),
163 Self::I16(v) => Some(*v as i32),
164 Self::U16(v) => Some(*v as i32),
165 Self::I32(v) => Some(*v),
166 Self::U32(v) => (*v).try_into().ok(),
167 _ => None,
168 }
169 }
170
171 pub fn as_u32(&self) -> Option<u32> {
172 match self {
173 Self::I8(v) => Some(*v as u32),
174 Self::U8(v) => Some(*v as u32),
175 Self::I16(v) => Some(*v as u32),
176 Self::U16(v) => Some(*v as u32),
177 Self::U32(v) => Some(*v),
178 Self::I32(v) => (*v).try_into().ok(),
179 _ => None,
180 }
181 }
182
183 pub fn as_f32(&self) -> Option<f32> {
184 match self {
185 Self::F32(v) => Some(*v),
186 _ => None,
187 }
188 }
189
190 pub fn as_hash(&self) -> Option<Hash40> {
191 match self {
192 Self::Hash(hash) => Some(*hash),
193 _ => None,
194 }
195 }
196
197 pub fn as_str(&self) -> Option<&str> {
198 match self {
199 Self::String(s) => Some(s.as_str()),
200 _ => None,
201 }
202 }
203
204 pub fn as_list(&self) -> Option<&[Value]> {
205 match self {
206 Self::List(list) => Some(list),
207 _ => None,
208 }
209 }
210
211 pub fn as_map(&self) -> Option<&IndexMap<Hash40, Value>> {
212 match self {
213 Self::Map(map) => Some(map),
214 _ => None,
215 }
216 }
217
218 pub fn merge(&mut self, other: &Value) {
219 match self {
220 Self::Bool(v) => {
221 if let Some(other) = other.as_bool() {
222 *v = other;
223 }
224 }
225 Self::I8(v) => {
226 if let Some(other) = other.as_i8() {
227 *v = other;
228 }
229 }
230 Self::U8(v) => {
231 if let Some(other) = other.as_u8() {
232 *v = other;
233 }
234 }
235 Self::I16(v) => {
236 if let Some(other) = other.as_i16() {
237 *v = other;
238 }
239 }
240 Self::U16(v) => {
241 if let Some(other) = other.as_u16() {
242 *v = other;
243 }
244 }
245 Self::I32(v) => {
246 if let Some(other) = other.as_i32() {
247 *v = other;
248 }
249 }
250 Self::U32(v) => {
251 if let Some(other) = other.as_u32() {
252 *v = other;
253 }
254 }
255 Self::F32(v) => {
256 if let Some(other) = other.as_f32() {
257 *v = other;
258 }
259 }
260 Self::Hash(v) => {
261 if let Some(other) = other.as_hash() {
262 *v = other;
263 }
264 }
265 Self::String(v) => {
266 if let Some(other) = other.as_str() {
267 *v = other.to_string();
268 }
269 }
270 Self::List(v) => {
271 if let Some(other) = other.as_list() {
272 v.iter_mut().zip(other).for_each(|(v, other)| {
273 v.merge(other);
274 });
275 }
276 }
277 Self::Map(v) => {
278 if let Some(other) = other.as_map() {
279 for (k, v) in v.iter_mut() {
280 if let Some(other) = other.get(k) {
281 v.merge(other);
282 }
283 }
284 }
285 }
286 }
287 }
288}
289
290pub fn from_reader<T: for<'de> Deserialize<'de>, R: std::io::Read + std::io::Seek>(
291 mut reader: R,
292) -> Result<T, de::Error> {
293 let mut magic = [0u8; 8];
295 reader.read_exact(&mut magic).unwrap();
296
297 assert_eq!(magic, *b"paracobn");
298
299 let hash_data_size = reader.read_u32::<LittleEndian>().unwrap();
300 assert_eq!(hash_data_size % 8, 0);
301 let ref_data_size = reader.read_u32::<LittleEndian>().unwrap();
302
303 let hashes: Vec<_> = (0..hash_data_size / 8)
304 .map(|_| Hash40(reader.read_u64::<LittleEndian>().unwrap()))
305 .collect();
306
307 let mut ref_data = Vec::with_capacity(ref_data_size as usize);
308 unsafe {
309 ref_data.set_len(ref_data_size as usize);
310 reader.read_exact(&mut ref_data).unwrap();
311 }
312
313 let mut deserializer = ValueDeserializer::new(
314 ReferenceData::new(ref_data, 8 + hash_data_size as usize),
315 &hashes,
316 &mut reader,
317 );
318
319 T::deserialize(&mut deserializer)
320}
321
322pub fn from_slice<T: for<'de> Deserialize<'de>>(bytes: &[u8]) -> Result<T, de::Error> {
323 from_reader(std::io::Cursor::new(bytes))
324}