serde_prc/
ser.rs

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}