serde_prc/
lib.rs

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    // Check magic
294    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}