1use std::{
2 collections::HashMap,
3 hash::{DefaultHasher, Hasher},
4 io::{Cursor, Write},
5};
6
7use byteorder::{LittleEndian, WriteBytesExt};
8use hash40::Hash40;
9use indexmap::{IndexMap, IndexSet};
10use serde::{
11 ser::{
12 Impossible, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple,
13 SerializeTupleStruct,
14 },
15 Serialize, Serializer,
16};
17
18use crate::{ParamId, Value};
19
20use thiserror::Error;
21
22#[derive(Debug, Error)]
23pub enum Error {
24 #[error("Unsupported key type: '{0}'")]
25 UnsupportedKeyType(&'static str),
26
27 #[error("Unsupported value type: '{0}'")]
28 UnsupportedValueType(&'static str),
29
30 #[error(transparent)]
31 IO(#[from] std::io::Error),
32
33 #[error("{0}")]
34 Custom(String),
35}
36
37impl serde::ser::Error for Error {
38 fn custom<T>(msg: T) -> Self
39 where
40 T: std::fmt::Display,
41 {
42 Self::Custom(msg.to_string())
43 }
44}
45
46pub struct IntoValueSerializer;
47
48pub struct ListSerializer(Vec<Value>);
49
50pub struct MapSerializer {
51 map: IndexMap<Hash40, Value>,
52 current_key: Option<Hash40>,
53}
54
55impl SerializeSeq for ListSerializer {
56 type Ok = Value;
57 type Error = Error;
58
59 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
60 where
61 T: Serialize,
62 {
63 self.0.push(value.serialize(IntoValueSerializer)?);
64 Ok(())
65 }
66
67 fn end(self) -> Result<Self::Ok, Self::Error> {
68 Ok(Value::List(self.0))
69 }
70}
71
72impl SerializeTuple for ListSerializer {
73 type Ok = Value;
74 type Error = Error;
75
76 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
77 where
78 T: Serialize,
79 {
80 self.0.push(value.serialize(IntoValueSerializer)?);
81 Ok(())
82 }
83
84 fn end(self) -> Result<Self::Ok, Self::Error> {
85 Ok(Value::List(self.0))
86 }
87}
88
89impl SerializeTupleStruct for ListSerializer {
90 type Ok = Value;
91 type Error = Error;
92
93 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
94 where
95 T: Serialize,
96 {
97 self.0.push(value.serialize(IntoValueSerializer)?);
98 Ok(())
99 }
100
101 fn end(self) -> Result<Self::Ok, Self::Error> {
102 Ok(Value::List(self.0))
103 }
104}
105
106impl SerializeMap for MapSerializer {
107 type Ok = Value;
108 type Error = Error;
109
110 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
111 where
112 T: Serialize,
113 {
114 let key = key.serialize(HashSerializer)?;
115 self.current_key = Some(key);
116 Ok(())
117 }
118
119 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
120 where
121 T: Serialize,
122 {
123 if !self.current_key.is_some() {
124 return Err(Error::Custom(
125 "attempting to serialize value with no key".to_string(),
126 ));
127 }
128
129 let value = value.serialize(IntoValueSerializer)?;
130 let key = self.current_key.take().unwrap();
131
132 self.map.insert(key, value);
133
134 Ok(())
135 }
136
137 fn end(self) -> Result<Self::Ok, Self::Error> {
138 Ok(Value::Map(self.map))
139 }
140}
141
142impl SerializeStruct for MapSerializer {
143 type Ok = Value;
144 type Error = Error;
145
146 fn serialize_field<T: ?Sized>(
147 &mut self,
148 key: &'static str,
149 value: &T,
150 ) -> Result<(), Self::Error>
151 where
152 T: Serialize,
153 {
154 let key = hash40::hash40(key);
155 let value = value.serialize(IntoValueSerializer)?;
156
157 self.map.insert(key, value);
158
159 Ok(())
160 }
161
162 fn end(self) -> Result<Self::Ok, Self::Error> {
163 Ok(Value::Map(self.map))
164 }
165}
166
167macro_rules! e {
168 ($e:literal) => {
169 Err(Error::UnsupportedValueType($e))
170 };
171}
172
173impl Serializer for IntoValueSerializer {
174 type Ok = Value;
175 type Error = Error;
176
177 type SerializeSeq = ListSerializer;
178
179 type SerializeTuple = ListSerializer;
180
181 type SerializeTupleStruct = ListSerializer;
182
183 type SerializeTupleVariant = Impossible<Value, Error>;
184
185 type SerializeMap = MapSerializer;
186
187 type SerializeStruct = MapSerializer;
188
189 type SerializeStructVariant = Impossible<Value, Error>;
190
191 fn is_human_readable(&self) -> bool {
192 false
193 }
194
195 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
196 Ok(Value::I8(v))
197 }
198
199 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
200 Ok(Value::U8(v))
201 }
202
203 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
204 Ok(Value::I16(v))
205 }
206
207 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
208 Ok(Value::U16(v))
209 }
210
211 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
212 Ok(Value::I32(v))
213 }
214
215 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
216 Ok(Value::U32(v))
217 }
218
219 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
220 Ok(Value::I32(
221 v.try_into().map_err(<Error as serde::ser::Error>::custom)?,
222 ))
223 }
224
225 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
226 Ok(Value::Hash(Hash40(v)))
227 }
228
229 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
230 Ok(Value::F32(v))
231 }
232
233 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
234 Ok(Value::F32(v as f32))
235 }
236
237 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
238 Ok(Value::String(v.to_string()))
239 }
240
241 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
242 Ok(Value::Bool(v))
243 }
244
245 fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
246 e!("char")
247 }
248
249 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
250 e!("&[u8]")
251 }
252
253 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
254 e!("none")
255 }
256
257 fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
258 where
259 T: Serialize,
260 {
261 e!("some")
262 }
263
264 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
265 e!("unit")
266 }
267
268 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
269 Ok(Value::String(name.to_string()))
270 }
271
272 fn serialize_unit_variant(
273 self,
274 _name: &'static str,
275 _variant_index: u32,
276 variant: &'static str,
277 ) -> Result<Self::Ok, Self::Error> {
278 Ok(Value::String(variant.to_string()))
279 }
280
281 fn serialize_newtype_struct<T: ?Sized>(
282 self,
283 _name: &'static str,
284 _value: &T,
285 ) -> Result<Self::Ok, Self::Error>
286 where
287 T: Serialize,
288 {
289 e!("newtype struct")
290 }
291
292 fn serialize_newtype_variant<T: ?Sized>(
293 self,
294 _name: &'static str,
295 _variant_index: u32,
296 _variant: &'static str,
297 _value: &T,
298 ) -> Result<Self::Ok, Self::Error>
299 where
300 T: Serialize,
301 {
302 e!("newtype variant")
303 }
304
305 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
306 Ok(ListSerializer(Vec::with_capacity(len.unwrap_or_default())))
307 }
308
309 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
310 Ok(ListSerializer(Vec::with_capacity(len)))
311 }
312
313 fn serialize_tuple_struct(
314 self,
315 _name: &'static str,
316 len: usize,
317 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
318 Ok(ListSerializer(Vec::with_capacity(len)))
319 }
320
321 fn serialize_tuple_variant(
322 self,
323 _name: &'static str,
324 _variant_index: u32,
325 _variant: &'static str,
326 _len: usize,
327 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
328 e!("tuple variant")
329 }
330
331 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
332 Ok(MapSerializer {
333 map: IndexMap::with_capacity(len.unwrap_or_default()),
334 current_key: None,
335 })
336 }
337
338 fn serialize_struct(
339 self,
340 _name: &'static str,
341 len: usize,
342 ) -> Result<Self::SerializeStruct, Self::Error> {
343 Ok(MapSerializer {
344 map: IndexMap::with_capacity(len),
345 current_key: None,
346 })
347 }
348
349 fn serialize_struct_variant(
350 self,
351 _name: &'static str,
352 _variant_index: u32,
353 _variant: &'static str,
354 _len: usize,
355 ) -> Result<Self::SerializeStructVariant, Self::Error> {
356 e!("struct variant")
357 }
358}
359
360impl Serialize for Value {
361 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
362 where
363 S: serde::Serializer,
364 {
365 match self {
366 Self::Bool(v) => serializer.serialize_bool(*v),
367 Self::I8(v) => serializer.serialize_i8(*v),
368 Self::U8(v) => serializer.serialize_u8(*v),
369 Self::I16(v) => serializer.serialize_i16(*v),
370 Self::U16(v) => serializer.serialize_u16(*v),
371 Self::I32(v) => serializer.serialize_i32(*v),
372 Self::U32(v) => serializer.serialize_u32(*v),
373 Self::F32(v) => serializer.serialize_f32(*v),
374 Self::Hash(v) => {
375 if serializer.is_human_readable() {
376 v.serialize(serializer)
377 } else {
378 v.0.serialize(serializer)
379 }
380 }
381 Self::String(v) => serializer.serialize_str(v),
382 Self::List(v) => {
383 let mut seq = serializer.serialize_seq(Some(v.len()))?;
384 for value in v.iter() {
385 seq.serialize_element(value)?;
386 }
387 seq.end()
388 }
389 Self::Map(v) => {
390 let is_human = serializer.is_human_readable();
391 let mut map = serializer.serialize_map(Some(v.len()))?;
392 for (k, v) in v.iter() {
393 if is_human {
394 map.serialize_entry(k, v)?;
395 } else {
396 map.serialize_entry(&k.0, v)?;
397 }
398 }
399 map.end()
400 }
401 }
402 }
403}
404
405struct HashSerializer;
406
407macro_rules! key_err {
408 ($e:literal) => {
409 Err(Error::UnsupportedKeyType($e))
410 };
411}
412
413impl Serializer for HashSerializer {
414 type Ok = Hash40;
415 type Error = Error;
416
417 type SerializeSeq = Impossible<Hash40, Error>;
418 type SerializeMap = Impossible<Hash40, Error>;
419 type SerializeTuple = Impossible<Hash40, Error>;
420 type SerializeTupleStruct = Impossible<Hash40, Error>;
421 type SerializeStruct = Impossible<Hash40, Error>;
422 type SerializeTupleVariant = Impossible<Hash40, Error>;
423 type SerializeStructVariant = Impossible<Hash40, Error>;
424
425 fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
426 key_err!("bool")
427 }
428
429 fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
430 key_err!("i8")
431 }
432
433 fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
434 key_err!("i16")
435 }
436
437 fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
438 key_err!("i32")
439 }
440
441 fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
442 key_err!("i64")
443 }
444
445 fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
446 key_err!("u8")
447 }
448
449 fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
450 key_err!("u16")
451 }
452
453 fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
454 key_err!("u32")
455 }
456
457 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
458 Ok(Hash40(v))
459 }
460
461 fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
462 key_err!("f32")
463 }
464
465 fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
466 key_err!("f64")
467 }
468
469 fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
470 key_err!("char")
471 }
472
473 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
474 Ok(hash40::hash40(v))
475 }
476
477 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
478 key_err!("&[u8]")
479 }
480
481 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
482 key_err!("none")
483 }
484
485 fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
486 where
487 T: Serialize,
488 {
489 key_err!("some")
490 }
491
492 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
493 key_err!("unit")
494 }
495
496 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
497 Ok(hash40::hash40(name))
498 }
499
500 fn serialize_unit_variant(
501 self,
502 _name: &'static str,
503 _variant_index: u32,
504 variant: &'static str,
505 ) -> Result<Self::Ok, Self::Error> {
506 Ok(hash40::hash40(variant))
507 }
508
509 fn serialize_newtype_struct<T: ?Sized>(
510 self,
511 _name: &'static str,
512 _value: &T,
513 ) -> Result<Self::Ok, Self::Error>
514 where
515 T: Serialize,
516 {
517 key_err!("newtype struct")
518 }
519
520 fn serialize_newtype_variant<T: ?Sized>(
521 self,
522 _name: &'static str,
523 _variant_index: u32,
524 _variant: &'static str,
525 _value: &T,
526 ) -> Result<Self::Ok, Self::Error>
527 where
528 T: Serialize,
529 {
530 key_err!("newtype variant")
531 }
532
533 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
534 key_err!("sequence")
535 }
536
537 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
538 key_err!("tuple")
539 }
540
541 fn serialize_tuple_struct(
542 self,
543 _name: &'static str,
544 _len: usize,
545 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
546 key_err!("tuple struct")
547 }
548
549 fn serialize_tuple_variant(
550 self,
551 _name: &'static str,
552 _variant_index: u32,
553 _variant: &'static str,
554 _len: usize,
555 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
556 key_err!("tuple variant")
557 }
558
559 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
560 key_err!("map")
561 }
562
563 fn serialize_struct(
564 self,
565 _name: &'static str,
566 _len: usize,
567 ) -> Result<Self::SerializeStruct, Self::Error> {
568 key_err!("struct")
569 }
570
571 fn serialize_struct_variant(
572 self,
573 _name: &'static str,
574 _variant_index: u32,
575 _variant: &'static str,
576 _len: usize,
577 ) -> Result<Self::SerializeStructVariant, Self::Error> {
578 key_err!("struct variant")
579 }
580}
581
582const fn prim<T: Sized>() -> usize {
583 1 + std::mem::size_of::<T>()
584}
585
586fn calculate_binary_size_of_value(value: &Value) -> usize {
587 match value {
588 Value::Bool(_) | Value::U8(_) | Value::I8(_) => prim::<u8>(),
589 Value::I16(_) | Value::U16(_) => prim::<u16>(),
590 Value::I32(_) | Value::U32(_) | Value::F32(_) | Value::String(_) | Value::Hash(_) => {
591 prim::<u32>()
592 }
593 Value::List(values) => {
594 prim::<u32>()
595 + values.len() * std::mem::size_of::<u32>()
596 + values
597 .iter()
598 .map(calculate_binary_size_of_value)
599 .sum::<usize>()
600 }
601 Value::Map(map) => {
602 prim::<u32>()
603 + std::mem::size_of::<u32>()
604 + map
605 .values()
606 .map(calculate_binary_size_of_value)
607 .sum::<usize>()
608 }
609 }
610}
611
612fn visit_hashes(lookup: &mut IndexSet<Hash40>, value: &Value) {
613 match value {
614 Value::Hash(hash) => {
615 lookup.insert(*hash);
616 }
617 Value::List(values) => {
618 values.iter().for_each(|value| visit_hashes(lookup, value));
619 }
620 Value::Map(values) => {
621 for (k, v) in values.iter() {
622 lookup.insert(*k);
623 visit_hashes(lookup, v);
624 }
625 }
626 _ => {}
627 }
628}
629
630fn visit_strings(data: &mut Vec<u8>, lookup: &mut HashMap<String, u32>, value: &Value) {
631 match value {
632 Value::String(string) if !lookup.contains_key(string) => {
633 let offset = data.len() as u32;
634 data.extend_from_slice(string.as_bytes());
635 data.push(b'\0');
636 lookup.insert(string.clone(), offset);
637 }
638 Value::List(values) => values
639 .iter()
640 .for_each(|value| visit_strings(data, lookup, value)),
641 Value::Map(map) => map
642 .values()
643 .for_each(|value| visit_strings(data, lookup, value)),
644 _ => {}
645 }
646}
647
648fn get_struct_key(map: &IndexMap<Hash40, Value>) -> u64 {
649 use std::hash::Hash;
650 let mut hasher = DefaultHasher::default();
651 for (key, value) in map.iter() {
652 key.hash(&mut hasher);
653 calculate_binary_size_of_value(value).hash(&mut hasher);
654 }
655
656 hasher.finish()
657}
658
659fn visit_structs(
660 hashes: &IndexSet<Hash40>,
661 data: &mut Vec<u8>,
662 lookup: &mut HashMap<u64, u32>,
663 value: &Value,
664) {
665 match value {
666 Value::List(list) => {
667 for value in list.iter() {
668 visit_structs(hashes, data, lookup, value);
669 }
670 }
671 Value::Map(map) => {
672 let key = get_struct_key(map);
673
674 if lookup.contains_key(&key) {
675 return;
676 }
677
678 let ref_offset = data.len() as u32;
679 let mut wip_offset = prim::<u32>() + std::mem::size_of::<u32>();
680 for (key, value) in map.iter() {
681 let key_index = hashes
682 .get_index_of(key)
683 .expect("should have cached the map key");
684 let value_offset = wip_offset;
685 wip_offset += calculate_binary_size_of_value(value);
686 data.write_u32::<LittleEndian>(key_index as u32)
687 .expect("writing to vec");
688 data.write_u32::<LittleEndian>(value_offset as u32)
689 .expect("writing to vec");
690 }
691
692 lookup.insert(key, ref_offset);
693
694 for value in map.values() {
695 visit_structs(hashes, data, lookup, value);
696 }
697 }
698 _ => {}
699 }
700}
701
702fn write_value<W: Write>(
703 writer: &mut W,
704 hashes: &IndexSet<Hash40>,
705 strings: &HashMap<String, u32>,
706 structs: &HashMap<u64, u32>,
707 value: &Value,
708) -> Result<(), Error> {
709 match value {
710 Value::Bool(v) => {
711 writer.write_u8(ParamId::Bool as u8)?;
712 writer.write_u8(*v as u8)?;
713 }
714 Value::I8(v) => {
715 writer.write_u8(ParamId::I8 as u8)?;
716 writer.write_i8(*v)?;
717 }
718 Value::U8(v) => {
719 writer.write_u8(ParamId::U8 as u8)?;
720 writer.write_u8(*v)?;
721 }
722 Value::I16(v) => {
723 writer.write_u8(ParamId::I16 as u8)?;
724 writer.write_i16::<LittleEndian>(*v)?;
725 }
726 Value::U16(v) => {
727 writer.write_u8(ParamId::U16 as u8)?;
728 writer.write_u16::<LittleEndian>(*v)?;
729 }
730 Value::I32(v) => {
731 writer.write_u8(ParamId::I32 as u8)?;
732 writer.write_i32::<LittleEndian>(*v)?;
733 }
734 Value::U32(v) => {
735 writer.write_u8(ParamId::U32 as u8)?;
736 writer.write_u32::<LittleEndian>(*v)?;
737 }
738 Value::F32(v) => {
739 writer.write_u8(ParamId::F32 as u8)?;
740 writer.write_f32::<LittleEndian>(*v)?;
741 }
742 Value::Hash(v) => {
743 writer.write_u8(ParamId::Hash as u8)?;
744 writer.write_u32::<LittleEndian>(
745 hashes.get_index_of(v).expect("should have cached hash") as u32,
746 )?;
747 }
748 Value::String(v) => {
749 writer.write_u8(ParamId::String as u8)?;
750 writer
751 .write_u32::<LittleEndian>(*strings.get(v).expect("should have cached string"))?;
752 }
753 Value::List(v) => {
754 writer.write_u8(ParamId::List as u8)?;
755 writer.write_u32::<LittleEndian>(v.len() as u32)?;
756 let mut wip_offset = (prim::<u32>() + v.len() * std::mem::size_of::<u32>()) as u32;
757 for value in v.iter() {
758 writer.write_u32::<LittleEndian>(wip_offset)?;
759 wip_offset += calculate_binary_size_of_value(value) as u32;
760 }
761 for value in v.iter() {
762 write_value(writer, hashes, strings, structs, value)?;
763 }
764 }
765 Value::Map(map) => {
766 writer.write_u8(ParamId::Map as u8)?;
767 writer.write_u32::<LittleEndian>(map.len() as u32)?;
768 writer.write_u32::<LittleEndian>(
769 *structs
770 .get(&get_struct_key(map))
771 .expect("should have cached struct"),
772 )?;
773 for value in map.values() {
774 write_value(writer, hashes, strings, structs, value)?;
775 }
776 }
777 }
778
779 Ok(())
780}
781
782pub fn write<W: Write, T: Serialize>(mut writer: W, value: &T) -> Result<(), Error> {
783 let value = value.serialize(IntoValueSerializer)?;
784
785 let mut hash_lookup = IndexSet::with_capacity(64);
786 let mut reference_data = Vec::with_capacity(128);
787 let mut string_lookup = HashMap::new();
788 let mut struct_lookup = HashMap::new();
789 visit_hashes(&mut hash_lookup, &value);
790 visit_strings(&mut reference_data, &mut string_lookup, &value);
791 visit_structs(
792 &hash_lookup,
793 &mut reference_data,
794 &mut struct_lookup,
795 &value,
796 );
797 writer.write_all(b"paracobn")?;
798
799 writer.write_u32::<LittleEndian>(8 * hash_lookup.len() as u32)?;
800 writer.write_u32::<LittleEndian>(reference_data.len() as u32)?;
801
802 for hash in hash_lookup.iter() {
803 writer.write_u64::<LittleEndian>(hash.0)?;
804 }
805
806 writer.write_all(&reference_data)?;
807
808 write_value(
809 &mut writer,
810 &hash_lookup,
811 &string_lookup,
812 &struct_lookup,
813 &value,
814 )?;
815
816 Ok(())
817}
818
819pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, Error> {
820 let mut writer = Cursor::new(Vec::with_capacity(256));
821 write(&mut writer, value)?;
822
823 Ok(writer.into_inner())
824}