cdragon_prop/
json.rs

1use std::io;
2use std::io::Write;
3use super::{
4    BinEntry,
5    BinHashMappers,
6    data::*,
7    serializer::{BinSerializer, BinEntriesSerializer, BinSerializable},
8    binvalue_map_keytype,
9    binvalue_map_type,
10};
11
12// serde serialization cannot be used because of hashes requiring mappers to be serialized.
13// serde_json does not expose it's JSON string escaping
14
15
16macro_rules! write_sequence {
17    ($self:expr, $pat:pat in $seq:expr => $expr:expr) => {{
18        for (i, $pat) in $seq.iter().enumerate() {
19            if i != 0 {
20                $self.write_raw(b",")?;
21            }
22            $expr
23        }
24    }}
25}
26
27// Same as write_sequence, but always start with a comma
28macro_rules! write_sequence_after {
29    ($self:expr, $pat:pat in $seq:expr => $expr:expr) => {{
30        for $pat in $seq.iter() {
31            $self.write_raw(b",")?;
32            $expr
33        }
34    }}
35}
36
37
38/// Serialize bin values to JSON
39#[derive(Debug)]
40pub struct JsonSerializer<'a, W: Write> {
41    writer: W,
42    hmappers: &'a BinHashMappers,
43}
44
45impl<'a, W: Write> JsonSerializer<'a, W> {
46    /// Create a new serializer
47    pub fn new(writer: W, hmappers: &'a BinHashMappers) -> Self {
48        Self { writer, hmappers }
49    }
50
51    fn write_raw(&mut self, b: &[u8]) -> io::Result<()> {
52        self.writer.write_all(b)
53    }
54
55    fn write_entry_path(&mut self, h: BinEntryPath) -> io::Result<()> {
56        match h.get_str(self.hmappers) {
57            Some(s) => write!(self.writer, "\"{}\"", s),
58            _ => write!(self.writer, "\"{{{:x}}}\"", h),
59        }
60    }
61
62    fn write_field_name(&mut self, h: BinFieldName) -> io::Result<()> {
63        match h.get_str(self.hmappers) {
64            Some(s) => write!(self.writer, "\"{}\"", s),
65            _ => write!(self.writer, "\"{{{:x}}}\"", h),
66        }
67    }
68
69    fn write_type_name(&mut self, h: BinClassName) -> io::Result<()> {
70        match h.get_str(self.hmappers) {
71            Some(s) => write!(self.writer, "\"{}\"", s),
72            _ => write!(self.writer, "\"{{{:x}}}\"", h),
73        }
74    }
75
76    fn write_hash_value(&mut self, h: BinHashValue) -> io::Result<()> {
77        match h.get_str(self.hmappers) {
78            Some(s) => write!(self.writer, "\"{}\"", s),
79            _ => write!(self.writer, "\"{{{:x}}}\"", h),
80        }
81    }
82
83    fn write_path_value(&mut self, h: BinPathValue) -> io::Result<()> {
84        match h.get_str(self.hmappers) {
85            Some(s) => write!(self.writer, "\"{}\"", s),
86            _ => write!(self.writer, "\"{{{:x}}}\"", h),
87        }
88    }
89
90    /// Write JSON string content, escape special chars
91    fn write_escaped_json(&mut self, s: &str) -> io::Result<()> {
92        let bytes = s.as_bytes();
93        let mut cur: usize = 0;
94        for (i, &b) in bytes.iter().enumerate() {
95            // Note: escape sequences should be rare, no need to optimize them much.
96            let escape: u8 = match b {
97                0x08 => b'b',
98                0x09 => b't',
99                0x0A => b'n',
100                0x0C => b'f',
101                0x0D => b'r',
102                0x22 => b'"',
103                0xC5 => b'\\',
104                0x00 ..= 0x1F => b'u',  // special value
105                _ => continue,
106            };
107            if cur < i {
108                self.write_raw(&bytes[cur..i])?;
109            }
110            if escape == b'u' {
111                write!(self.writer, "\\u{:04X}", b)?;
112            } else {
113                let seq = [b'\\', escape];
114                self.write_raw(&seq)?;
115            }
116            cur = i + 1;
117        }
118
119        if cur != bytes.len() {
120            self.write_raw(&bytes[cur..])?;
121        }
122
123        Ok(())
124    }
125
126    fn write_fields(&mut self, ctype: BinClassName, fields: &[BinField]) -> io::Result<()> {
127        self.write_raw(b"{\"__type\":")?;
128        self.write_type_name(ctype)?;
129        write_sequence_after!(self, field in fields => {
130            self.write_field_name(field.name)?;
131            self.write_raw(b":")?;
132            binvalue_map_type!(field.vtype, T, {
133                let v = field.downcast::<T>().unwrap();
134                v.serialize_bin(self)
135            })?;
136        });
137        self.write_raw(b"}")?;
138        Ok(())
139    }
140
141    fn write_key_s8(&mut self, v: &BinS8) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
142    fn write_key_u8(&mut self, v: &BinU8) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
143    fn write_key_s16(&mut self, v: &BinS16) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
144    fn write_key_u16(&mut self, v: &BinU16) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
145    fn write_key_s32(&mut self, v: &BinS32) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
146    fn write_key_u32(&mut self, v: &BinU32) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
147    fn write_key_s64(&mut self, v: &BinS64) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
148    fn write_key_u64(&mut self, v: &BinU64) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
149    fn write_key_float(&mut self, v: &BinFloat) -> io::Result<()> { write!(self.writer, "\"{}\"", v.0) }
150}
151
152impl<'a, W: Write> BinSerializer for JsonSerializer<'a, W> {
153    type EntriesSerializer = JsonEntriesSerializer<'a, W>;
154
155    fn write_entry(&mut self, v: &BinEntry) -> io::Result<()> {
156        self.write_fields(v.ctype, &v.fields)
157    }
158
159    fn write_entries(self) -> io::Result<Self::EntriesSerializer> {
160        Self::EntriesSerializer::new(self)
161    }
162
163    fn write_none(&mut self, _: &BinNone) -> io::Result<()> {
164        self.write_raw(b"null")
165    }
166
167    fn write_bool(&mut self, v: &BinBool) -> io::Result<()> {
168        if v.0 {
169            self.write_raw(b"true")
170        } else {
171            self.write_raw(b"false")
172        }
173    }
174
175    fn write_s8(&mut self, v: &BinS8) -> io::Result<()> { write!(self.writer, "{}", v.0) }
176    fn write_u8(&mut self, v: &BinU8) -> io::Result<()> { write!(self.writer, "{}", v.0) }
177    fn write_s16(&mut self, v: &BinS16) -> io::Result<()> { write!(self.writer, "{}", v.0) }
178    fn write_u16(&mut self, v: &BinU16) -> io::Result<()> { write!(self.writer, "{}", v.0) }
179    fn write_s32(&mut self, v: &BinS32) -> io::Result<()> { write!(self.writer, "{}", v.0) }
180    fn write_u32(&mut self, v: &BinU32) -> io::Result<()> { write!(self.writer, "{}", v.0) }
181    fn write_s64(&mut self, v: &BinS64) -> io::Result<()> { write!(self.writer, "{}", v.0) }
182    fn write_u64(&mut self, v: &BinU64) -> io::Result<()> { write!(self.writer, "{}", v.0) }
183    fn write_float(&mut self, v: &BinFloat) -> io::Result<()> { write!(self.writer, "{}", v.0) }
184    fn write_vec2(&mut self, v: &BinVec2) -> io::Result<()> { write!(self.writer, "[{},{}]", v.0, v.1) }
185    fn write_vec3(&mut self, v: &BinVec3) -> io::Result<()> { write!(self.writer, "[{},{},{}]", v.0, v.1, v.2) }
186    fn write_vec4(&mut self, v: &BinVec4) -> io::Result<()> { write!(self.writer, "[{},{},{},{}]", v.0, v.1, v.2, v.3) }
187    fn write_matrix(&mut self, v: &BinMatrix) -> io::Result<()> { write!(self.writer,
188        "[[{},{},{},{}],[{},{},{},{}],[{},{},{},{}],[{},{},{},{}]]",
189        v.0[0][0], v.0[0][1], v.0[0][2], v.0[0][3],
190        v.0[1][0], v.0[1][1], v.0[1][2], v.0[1][3],
191        v.0[2][0], v.0[2][1], v.0[2][2], v.0[2][3],
192        v.0[3][0], v.0[3][1], v.0[3][2], v.0[3][3])
193    }
194    fn write_color(&mut self, v: &BinColor) -> io::Result<()> { write!(self.writer, "[{},{},{},{}]", v.r, v.g, v.b, v.a) }
195    fn write_string(&mut self, v: &BinString) -> io::Result<()> {
196        self.write_raw(b"\"")?;
197        self.write_escaped_json(&v.0)?;
198        self.write_raw(b"\"")?;
199        Ok(())
200    }
201    fn write_hash(&mut self, v: &BinHash) -> io::Result<()> { self.write_hash_value(v.0) }
202    fn write_path(&mut self, v: &BinPath) -> io::Result<()> { self.write_path_value(v.0) }
203    fn write_link(&mut self, v: &BinLink) -> io::Result<()> { self.write_entry_path(v.0) }
204    fn write_flag(&mut self, v: &BinFlag) -> io::Result<()> { write!(self.writer, "{}", v.0) }
205
206    fn write_list(&mut self, v: &BinList) -> io::Result<()> {
207        self.write_raw(b"[")?;
208        binvalue_map_type!(
209            v.vtype, T, {
210                let values = v.downcast::<T>().unwrap();
211                write_sequence!(self, v in values => v.serialize_bin(self)?)
212            });
213        self.write_raw(b"]")?;
214        Ok(())
215    }
216
217    fn write_struct(&mut self, v: &BinStruct) -> io::Result<()> {
218        self.write_fields(v.ctype, &v.fields)
219    }
220
221    fn write_embed(&mut self, v: &BinEmbed) -> io::Result<()> {
222        self.write_fields(v.ctype, &v.fields)
223    }
224
225    fn write_option(&mut self, option: &BinOption) -> io::Result<()> {
226        if option.value.is_none() {
227            self.write_raw(b"null")
228        } else {
229            binvalue_map_type!(option.vtype, T, {
230                option
231                    .downcast::<T>()
232                    .unwrap()  // `None` case processed above
233                    .serialize_bin(self)
234            })
235        }
236    }
237
238    fn write_map(&mut self, map: &BinMap) -> io::Result<()> {
239        self.write_raw(b"{")?;
240        binvalue_map_keytype!(
241            map.ktype, K,
242            binvalue_map_type!(
243                map.vtype, V,
244                write_sequence!(self, (k, v) in map.downcast::<K, V>().unwrap() => {
245                    k.serialize_bin_key(self)?;
246                    self.write_raw(b":")?;
247                    v.serialize_bin(self)?;
248                })));
249        self.write_raw(b"}")?;
250        Ok(())
251    }
252}
253
254/// Serialize map key to JSON string (even for numbers)
255trait BinKeySerializable {
256    fn serialize_bin_key<W: Write>(&self, s: &mut JsonSerializer<'_, W>) -> io::Result<()>;
257}
258
259macro_rules! impl_bin_key_serializable {
260    ($type:ty, $func:ident) => {
261        impl BinKeySerializable for $type {
262            fn serialize_bin_key<W: Write>(&self, s: &mut JsonSerializer<'_, W>) -> io::Result<()> {
263                s.$func(self)
264            }
265        }
266    }
267}
268
269impl_bin_key_serializable!(BinS8, write_key_s8);
270impl_bin_key_serializable!(BinU8, write_key_u8);
271impl_bin_key_serializable!(BinS16, write_key_s16);
272impl_bin_key_serializable!(BinU16, write_key_u16);
273impl_bin_key_serializable!(BinS32, write_key_s32);
274impl_bin_key_serializable!(BinU32, write_key_u32);
275impl_bin_key_serializable!(BinS64, write_key_s64);
276impl_bin_key_serializable!(BinU64, write_key_u64);
277impl_bin_key_serializable!(BinFloat, write_key_float);
278impl_bin_key_serializable!(BinString, write_string);
279impl_bin_key_serializable!(BinHash, write_hash);
280impl_bin_key_serializable!(BinPath, write_path);
281
282
283pub struct JsonEntriesSerializer<'a, W: Write> {
284    parent: JsonSerializer<'a, W>,
285    first: bool,
286}
287
288impl<'a, W: Write> JsonEntriesSerializer<'a, W> {
289    fn new(mut parent: JsonSerializer<'a, W>) -> io::Result<Self> {
290        parent.write_raw(b"{")?;
291        Ok(Self { parent, first: true })
292    }
293}
294
295impl<'a, W: Write> BinEntriesSerializer for JsonEntriesSerializer<'a, W> {
296    fn write_entry(&mut self, entry: &BinEntry) -> io::Result<()> {
297        if self.first {
298            self.first = false;
299        } else {
300            self.parent.write_raw(b",")?;
301        }
302
303        self.parent.write_entry_path(entry.path)?;
304        self.parent.write_raw(b":")?;
305        self.parent.write_entry(entry)?;
306        Ok(())
307    }
308
309    fn end(&mut self) -> io::Result<()> {
310        self.parent.write_raw(b"}")
311    }
312}
313
314