Skip to main content

blaze_pk/
types.rs

1//! Types implementation for custom types used while encoding values
2//! with Blaze packets
3
4use crate::codec::{Decodable, Encodable, ValueType};
5use crate::error::{DecodeError, DecodeResult};
6use crate::reader::TdfReader;
7use crate::tag::{Tag, TdfType};
8use crate::value_type;
9use crate::writer::TdfWriter;
10use std::borrow::Borrow;
11use std::collections::HashMap;
12use std::fmt::Debug;
13use std::{slice, vec};
14
15/// List of Var ints
16#[derive(Debug, PartialEq, Eq)]
17pub struct VarIntList<T>(pub Vec<T>);
18
19impl<T> Default for VarIntList<T> {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl<T> VarIntList<T> {
26    /// Creates a new VarIntList
27    pub fn new() -> Self {
28        Self(Vec::new())
29    }
30
31    /// Creates a new VarIntList with no capacity
32    pub fn empty() -> Self {
33        Self(Vec::with_capacity(0))
34    }
35
36    /// Creates a new VarIntList with the provided
37    /// capacity
38    ///
39    /// `capacity` The capacity for the underlying list
40    pub fn with_capacity(capacity: usize) -> Self {
41        Self(Vec::with_capacity(capacity))
42    }
43
44    /// Pushes a new value into the underlying list
45    ///
46    /// `value` The value to push
47    pub fn push(&mut self, value: impl Into<T>) {
48        self.0.push(value.into())
49    }
50
51    /// Removes the value at the provided index and returns
52    /// the value stored at it if there is one
53    ///
54    /// `index` The index to remove
55    pub fn remove(&mut self, index: usize) -> Option<T> {
56        if index < self.0.len() {
57            Some(self.0.remove(index))
58        } else {
59            None
60        }
61    }
62
63    /// Retrieves the value at the provided index returning
64    /// a borrow if one is there
65    ///
66    /// `index` The index to get the value at
67    pub fn get(&mut self, index: usize) -> Option<&T> {
68        self.0.get(index)
69    }
70}
71
72impl<C> Encodable for VarIntList<C>
73where
74    C: VarInt,
75{
76    fn encode(&self, output: &mut TdfWriter) {
77        output.write_usize(self.0.len());
78        for value in &self.0 {
79            value.encode(output);
80        }
81    }
82}
83
84impl<C> Decodable for VarIntList<C>
85where
86    C: VarInt,
87{
88    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
89        let length = reader.read_usize()?;
90        let mut out = Vec::with_capacity(length);
91        for _ in 0..length {
92            out.push(C::decode(reader)?);
93        }
94        Ok(VarIntList(out))
95    }
96}
97
98impl<C> ValueType for VarIntList<C> {
99    fn value_type() -> TdfType {
100        TdfType::VarIntList
101    }
102}
103
104/// Type that can be unset or contain a pair of key
105/// values
106#[derive(Debug, PartialEq, Eq)]
107pub enum Union<C> {
108    /// Set variant of a union value
109    Set { key: u8, tag: Tag, value: C },
110    /// Unset variant of a union value
111    Unset,
112}
113
114impl<C> Union<C> {
115    /// Creates a new union with a unset value
116    pub fn unset() -> Self {
117        Self::Unset
118    }
119
120    /// Creates a new set union value with the provided
121    /// key tag and value
122    pub fn set(key: u8, tag: &[u8], value: C) -> Self {
123        Self::Set {
124            key,
125            tag: tag.into(),
126            value,
127        }
128    }
129
130    /// Checks if the union is of set type
131    pub fn is_set(&self) -> bool {
132        matches!(self, Self::Set { .. })
133    }
134
135    /// Checks if the union is of unset type
136    pub fn is_unset(&self) -> bool {
137        matches!(self, Self::Unset)
138    }
139
140    /// Unwraps the underlying value stored in this union panicing if the
141    /// value is unset
142    pub fn unwrap(self) -> C {
143        match self {
144            Self::Unset => panic!("Attempted to unwrap union with no value"),
145            Self::Set { value, .. } => value,
146        }
147    }
148}
149
150impl<C> From<Union<C>> for Option<C> {
151    fn from(value: Union<C>) -> Self {
152        match value {
153            Union::Set { value, .. } => Some(value),
154            Union::Unset => None,
155        }
156    }
157}
158
159impl<C> ValueType for Union<C> {
160    fn value_type() -> TdfType {
161        TdfType::Union
162    }
163}
164
165impl<C> Encodable for Union<C>
166where
167    C: Encodable + ValueType,
168{
169    fn encode(&self, output: &mut TdfWriter) {
170        match self {
171            Union::Set { key, tag, value } => {
172                output.write_byte(*key);
173                output.tag(&tag.0, C::value_type());
174                value.encode(output);
175            }
176            Union::Unset => output.write_byte(UNION_UNSET),
177        }
178    }
179}
180
181impl<C> Decodable for Union<C>
182where
183    C: Decodable + ValueType,
184{
185    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
186        let key = reader.read_byte()?;
187        if key == UNION_UNSET {
188            return Ok(Union::Unset);
189        }
190        let tag = reader.read_tag()?;
191        let expected_type = C::value_type();
192        let actual_type = tag.ty;
193        if actual_type != expected_type {
194            return Err(DecodeError::InvalidType {
195                expected: expected_type,
196                actual: actual_type,
197            });
198        }
199        let value = C::decode(reader)?;
200
201        Ok(Union::Set {
202            key,
203            tag: tag.tag,
204            value,
205        })
206    }
207}
208
209/// Key value for unions that are unset
210pub const UNION_UNSET: u8 = 0x7F;
211
212/// Trait implemented by VarInt types
213pub trait VarInt: PartialEq + Eq + Debug + Encodable + Decodable {}
214
215/// Trait that must be implemented on a type for it to
216/// be considered a map key
217pub trait MapKey: PartialEq + Eq + Debug {}
218
219impl MapKey for &'_ str {}
220impl MapKey for String {}
221impl<T: VarInt> MapKey for T {}
222
223/// Macro for implementing the var int trait in bulk easily
224macro_rules! impl_var_int {
225    ($($ty:ty),*) => { $(impl VarInt for $ty {})* };
226}
227
228impl_var_int!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
229
230/// Structure for maps used in the protocol. These maps have a special
231/// order that is usually required and they retain the order of insertion
232/// because it uses two vecs as the underlying structure
233pub struct TdfMap<K, V> {
234    /// The entries stored in this map
235    entries: Vec<MapEntry<K, V>>,
236}
237
238/// Entry within a TdfMap storing a key value pair
239struct MapEntry<K, V> {
240    /// Entry key
241    key: K,
242    /// Entry value
243    value: V,
244}
245
246impl<K, V> Clone for MapEntry<K, V>
247where
248    K: Clone,
249    V: Clone,
250{
251    fn clone(&self) -> Self {
252        Self {
253            key: self.key.clone(),
254            value: self.value.clone(),
255        }
256    }
257}
258
259impl<K, V> Default for TdfMap<K, V> {
260    fn default() -> Self {
261        Self {
262            entries: Vec::new(),
263        }
264    }
265}
266
267impl<K, V> Clone for TdfMap<K, V>
268where
269    K: Clone,
270    V: Clone,
271{
272    fn clone(&self) -> Self {
273        Self {
274            entries: self.entries.clone(),
275        }
276    }
277}
278
279impl<K, V> Debug for TdfMap<K, V>
280where
281    K: Debug,
282    V: Debug,
283{
284    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285        f.write_str("TdfMap {")?;
286        for (key, value) in self.iter() {
287            writeln!(f, "  {key:?}: {value:?}")?;
288        }
289        f.write_str("}")
290    }
291}
292
293impl<K, V> TdfMap<K, V> {
294    /// Constructor implemention just uses the underlying default
295    /// implemenation
296    pub fn new() -> Self {
297        Self::default()
298    }
299
300    /// Function for creating a new TdfMap where the underlying
301    /// lists have an initial capacity
302    ///
303    /// `capacity` The capacity
304    pub fn with_capacity(capacity: usize) -> Self {
305        Self {
306            entries: Vec::with_capacity(capacity),
307        }
308    }
309
310    /// Returns the length of the underlying lists
311    pub fn len(&self) -> usize {
312        self.entries.len()
313    }
314
315    /// Returns if the underlying lists are empty
316    pub fn is_empty(&self) -> bool {
317        self.entries.is_empty()
318    }
319
320    /// Creates a new iterator over the underlying items
321    /// in the map
322    pub fn iter(&self) -> MapEntryIter<'_, K, V> {
323        MapEntryIter {
324            inner: self.entries.iter(),
325        }
326    }
327
328    /// Returns the key and value stored at the provided index
329    /// will return None if there is nothing at the provided index
330    pub fn index(&self, index: usize) -> Option<(&'_ K, &'_ V)> {
331        let entry = self.entries.get(index)?;
332        Some((&entry.key, &entry.value))
333    }
334
335    /// Inserts a new key value pair into the underlying structure.
336    ///
337    /// This function does NOT maintain order of the entires, use
338    /// `insert_ordered` instead for maintaining the order
339    ///
340    /// `key`   The entry key
341    /// `value` The entry value
342    pub fn insert<A: Into<K>, B: Into<V>>(&mut self, key: A, value: B) {
343        self.entries.push(MapEntry {
344            key: key.into(),
345            value: value.into(),
346        });
347    }
348
349    /// Removes the last key and value returning them or None
350    /// if there are no entries
351    pub fn pop(&mut self) -> Option<(K, V)> {
352        let entry = self.entries.pop()?;
353        Some((entry.key, entry.value))
354    }
355
356    /// Removes all entries from the underlying list
357    pub fn clear(&mut self) {
358        self.entries.clear();
359    }
360}
361
362impl<K, V> TdfMap<K, V>
363where
364    K: PartialOrd + Ord,
365{
366    /// Orders this map based on its keys by ordering keys that
367    /// are greater further up in the map
368    ///
369    /// This function is quite slow compared to using `insert_ordered`
370    /// for all the inserted entries. This is only for if you inserted
371    /// with `insert` instead
372    pub fn order(&mut self) {
373        let entries = &mut self.entries;
374        let length = entries.len();
375        // If empty or 1 item no need to order
376        if length <= 1 {
377            return;
378        }
379
380        entries.sort_by(|a, b| a.key.cmp(&b.key));
381    }
382}
383
384impl<K, V> TdfMap<K, V>
385where
386    K: PartialEq + Eq,
387{
388    /// Extends this map with the contents of another map. Any keys that already
389    /// exist in the map will be replaced with the keys from the other map
390    /// and any keys not present will be inserted
391    ///
392    /// `other` The map to extend with
393    pub fn extend(&mut self, other: TdfMap<K, V>) {
394        for MapEntry { key, value } in other.entries {
395            let key_index: Option<usize> = self.entries.iter().position(|value| key.eq(&value.key));
396            if let Some(index) = key_index {
397                self.entries[index].value = value;
398            } else {
399                self.insert(key, value);
400            }
401        }
402    }
403
404    /// Returns the index of the provided key or None if
405    /// the key was not present
406    ///
407    /// `key` The key to find the index of
408    fn index_of_key<Q: ?Sized>(&self, key: &Q) -> Option<usize>
409    where
410        K: Borrow<Q>,
411        Q: Eq,
412    {
413        for index in 0..self.entries.len() {
414            let entry_at = &self.entries[index];
415            let key_at = entry_at.key.borrow();
416            if key_at.eq(key) {
417                return Some(index);
418            }
419        }
420        None
421    }
422
423    /// Removes a value by its key and returns the entry
424    /// that was present at that position.
425    ///
426    /// `key` The key to remove
427    pub fn remove(&mut self, key: &K) -> Option<(K, V)> {
428        let index = self.index_of_key(key)?;
429        let entry = self.entries.remove(index);
430        Some((entry.key, entry.value))
431    }
432
433    /// Returns the value stored at the provided key if
434    /// its present or None.
435    ///
436    /// `key` The key to retrieve the value for
437    #[inline]
438    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
439    where
440        K: Borrow<Q>,
441        Q: Eq,
442    {
443        let index = self.index_of_key(key)?;
444        let entry = self.entries.get(index)?;
445        Some(&entry.value)
446    }
447
448    /// Returns a mutable borrow to the value stored at the
449    /// provided key if its present or None.
450    ///
451    /// `key` The key to retrieve the value for
452    #[inline]
453    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
454    where
455        K: Borrow<Q>,
456        Q: Eq,
457    {
458        let index = self.index_of_key(key)?;
459        let entry = self.entries.get_mut(index)?;
460
461        Some(&mut entry.value)
462    }
463
464    /// Takes the value stored at the provided key out of
465    /// the map taking ownership this also removes the key.
466    pub fn get_owned<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
467    where
468        K: Borrow<Q>,
469        Q: Eq,
470    {
471        let index = self.index_of_key(key)?;
472        let entry = self.entries.remove(index);
473        Some(entry.value)
474    }
475}
476
477/// Iterator implementation for iterating over TdfMap
478pub struct MapEntryIter<'a, K, V> {
479    /// The underlying map entry iterator
480    inner: slice::Iter<'a, MapEntry<K, V>>,
481}
482
483impl<'a, K, V> Iterator for MapEntryIter<'a, K, V> {
484    type Item = (&'a K, &'a V);
485
486    fn next(&mut self) -> Option<Self::Item> {
487        let next = self.inner.next()?;
488
489        Some((&next.key, &next.value))
490    }
491}
492
493/// Iterator type sitting ontop of the map entries to
494/// produce unions of the key values from the vec of
495/// map entries
496pub struct OwnedMapEntryIter<K, V> {
497    /// The underlying entry iterator
498    inner: vec::IntoIter<MapEntry<K, V>>,
499}
500
501impl<K, V> Iterator for OwnedMapEntryIter<K, V> {
502    type Item = (K, V);
503
504    fn next(&mut self) -> Option<Self::Item> {
505        let MapEntry { key, value } = self.inner.next()?;
506        Some((key, value))
507    }
508}
509
510/// Into iterator implementation for owned map
511impl<K, V> IntoIterator for TdfMap<K, V> {
512    type Item = (K, V);
513    type IntoIter = OwnedMapEntryIter<K, V>;
514
515    fn into_iter(self) -> Self::IntoIter {
516        OwnedMapEntryIter {
517            inner: self.entries.into_iter(),
518        }
519    }
520}
521
522/// Into iterator implementation for borrowed map
523impl<'a, K, V> IntoIterator for &'a TdfMap<K, V> {
524    type Item = (&'a K, &'a V);
525    type IntoIter = MapEntryIter<'a, K, V>;
526
527    fn into_iter(self) -> Self::IntoIter {
528        MapEntryIter {
529            inner: self.entries.iter(),
530        }
531    }
532}
533
534impl<K, V> Encodable for TdfMap<K, V>
535where
536    K: Encodable + ValueType,
537    V: Encodable + ValueType,
538{
539    fn encode(&self, output: &mut TdfWriter) {
540        output.write_map_header(K::value_type(), V::value_type(), self.len());
541
542        for MapEntry { key, value } in &self.entries {
543            key.encode(output);
544            value.encode(output);
545        }
546    }
547}
548
549impl<K, V> Decodable for TdfMap<K, V>
550where
551    K: Decodable + ValueType,
552    V: Decodable + ValueType,
553{
554    #[inline]
555    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
556        reader.read_map()
557    }
558}
559
560impl<K, V> ValueType for TdfMap<K, V> {
561    fn value_type() -> TdfType {
562        TdfType::Map
563    }
564}
565
566/// Implementation for converting a HashMap to a TdfMap by taking
567/// all its keys and values and building lists for the TdfMap
568impl<K, V> From<HashMap<K, V>> for TdfMap<K, V> {
569    fn from(map: HashMap<K, V>) -> Self {
570        let mut entries: Vec<MapEntry<K, V>> = Vec::with_capacity(map.len());
571
572        for (key, value) in map.into_iter() {
573            entries.push(MapEntry { key, value });
574        }
575
576        Self { entries }
577    }
578}
579
580impl Encodable for f32 {
581    #[inline]
582    fn encode(&self, output: &mut TdfWriter) {
583        output.write_f32(*self)
584    }
585}
586
587impl Decodable for f32 {
588    #[inline]
589    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
590        reader.read_f32()
591    }
592}
593
594value_type!(f32, TdfType::Float);
595
596impl Encodable for bool {
597    #[inline]
598    fn encode(&self, output: &mut TdfWriter) {
599        output.write_bool(*self)
600    }
601}
602
603impl Decodable for bool {
604    #[inline]
605    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
606        reader.read_bool()
607    }
608}
609
610value_type!(bool, TdfType::VarInt);
611
612/// Macro for forwarding the encode and decodes of a type to
613/// another types encoder and decoder
614///
615/// `$a` The type to forward
616/// `$b` The type to forward to
617macro_rules! forward_codec {
618    ($a:ident, $b:ident) => {
619        impl Decodable for $a {
620            #[inline]
621            fn decode(reader: &mut $crate::reader::TdfReader) -> $crate::error::DecodeResult<Self> {
622                Ok($b::decode(reader)? as $a)
623            }
624        }
625
626        impl Encodable for $a {
627            #[inline]
628            fn encode(&self, output: &mut TdfWriter) {
629                $b::encode(&(*self as $b), output)
630            }
631        }
632
633        impl $crate::codec::ValueType for $a {
634            #[inline]
635            fn value_type() -> TdfType {
636                $b::value_type()
637            }
638        }
639    };
640}
641
642// Encoding for u8 values
643
644impl Encodable for u8 {
645    #[inline]
646    fn encode(&self, output: &mut TdfWriter) {
647        output.write_u8(*self)
648    }
649}
650
651impl Decodable for u8 {
652    #[inline]
653    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
654        reader.read_u8()
655    }
656}
657
658impl Encodable for u16 {
659    #[inline]
660    fn encode(&self, output: &mut TdfWriter) {
661        output.write_u16(*self)
662    }
663}
664
665impl Decodable for u16 {
666    #[inline]
667    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
668        reader.read_u16()
669    }
670}
671
672impl Encodable for u32 {
673    #[inline]
674    fn encode(&self, output: &mut TdfWriter) {
675        output.write_u32(*self)
676    }
677}
678
679impl Decodable for u32 {
680    #[inline]
681    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
682        reader.read_u32()
683    }
684}
685
686impl Encodable for u64 {
687    #[inline]
688    fn encode(&self, output: &mut TdfWriter) {
689        output.write_u64(*self)
690    }
691}
692
693impl Decodable for u64 {
694    #[inline]
695    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
696        reader.read_u64()
697    }
698}
699
700impl Encodable for usize {
701    #[inline]
702    fn encode(&self, output: &mut TdfWriter) {
703        output.write_usize(*self)
704    }
705}
706
707impl Decodable for usize {
708    #[inline]
709    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
710        reader.read_usize()
711    }
712}
713
714value_type!(u8, TdfType::VarInt);
715value_type!(u16, TdfType::VarInt);
716value_type!(u32, TdfType::VarInt);
717value_type!(u64, TdfType::VarInt);
718value_type!(usize, TdfType::VarInt);
719
720forward_codec!(i8, u8);
721forward_codec!(i16, u16);
722forward_codec!(i32, u32);
723forward_codec!(i64, u64);
724forward_codec!(isize, usize);
725
726impl Encodable for &'_ str {
727    #[inline]
728    fn encode(&self, output: &mut TdfWriter) {
729        output.write_str(self)
730    }
731}
732
733value_type!(&'_ str, TdfType::String);
734
735impl Encodable for String {
736    #[inline]
737    fn encode(&self, output: &mut TdfWriter) {
738        output.write_str(self);
739    }
740}
741
742impl Decodable for String {
743    #[inline]
744    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
745        reader.read_string()
746    }
747}
748
749value_type!(String, TdfType::String);
750
751/// Blob structure wrapping a vec of bytes. This implementation is
752/// to differenciate between a list of VarInts and a Blob of straight
753/// bytes
754#[derive(Default, Debug, Clone)]
755pub struct Blob(pub Vec<u8>);
756
757impl Encodable for Blob {
758    fn encode(&self, output: &mut TdfWriter) {
759        output.write_usize(self.0.len());
760        output.write_slice(&self.0);
761    }
762}
763
764impl Decodable for Blob {
765    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
766        let length = reader.read_usize()?;
767        let bytes = reader.read_slice(length)?;
768        Ok(Blob(bytes.to_vec()))
769    }
770}
771
772value_type!(Blob, TdfType::Blob);
773
774/// Vec List encoding for encodable items items are required
775/// to have the ValueType trait in order to write the list header
776impl<C> Encodable for Vec<C>
777where
778    C: Encodable + ValueType,
779{
780    fn encode(&self, writer: &mut TdfWriter) {
781        writer.write_type(C::value_type());
782        writer.write_usize(self.len());
783        for value in self {
784            value.encode(writer);
785        }
786    }
787}
788
789/// Support for encoding slices of encodable items as lists
790impl<C> Encodable for &[C]
791where
792    C: Encodable + ValueType,
793{
794    fn encode(&self, writer: &mut TdfWriter) {
795        writer.write_type(C::value_type());
796        writer.write_usize(self.len());
797        for value in self.iter() {
798            value.encode(writer);
799        }
800    }
801}
802
803impl<C> ValueType for &[C]
804where
805    C: Encodable + ValueType,
806{
807    fn value_type() -> TdfType {
808        TdfType::List
809    }
810}
811
812impl<C> Decodable for Vec<C>
813where
814    C: Decodable + ValueType,
815{
816    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
817        let value_type: TdfType = reader.read_type()?;
818        let expected_type = C::value_type();
819        if value_type != expected_type {
820            return Err(DecodeError::InvalidType {
821                expected: expected_type,
822                actual: value_type,
823            });
824        }
825
826        let length = reader.read_usize()?;
827        let mut values = Vec::with_capacity(length);
828        for _ in 0..length {
829            values.push(C::decode(reader)?);
830        }
831        Ok(values)
832    }
833}
834
835impl<C> ValueType for Vec<C> {
836    fn value_type() -> TdfType {
837        TdfType::List
838    }
839}
840
841/// Pair type alias. (Note Pairs should only ever be used with VarInts)
842pub type Pair<A, B> = (A, B);
843
844impl<A, B> Encodable for Pair<A, B>
845where
846    A: VarInt,
847    B: VarInt,
848{
849    fn encode(&self, output: &mut TdfWriter) {
850        self.0.encode(output);
851        self.1.encode(output);
852    }
853}
854
855impl<A, B> Decodable for Pair<A, B>
856where
857    A: VarInt,
858    B: VarInt,
859{
860    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
861        let a = A::decode(reader)?;
862        let b = B::decode(reader)?;
863        Ok((a, b))
864    }
865}
866
867impl<A, B> ValueType for Pair<A, B> {
868    fn value_type() -> TdfType {
869        TdfType::Pair
870    }
871}
872
873/// Triple type alias. (Note Triples should only ever be used with VarInts)
874pub type Triple<A, B, C> = (A, B, C);
875
876impl<A, B, C> Encodable for Triple<A, B, C>
877where
878    A: VarInt,
879    B: VarInt,
880    C: VarInt,
881{
882    fn encode(&self, output: &mut TdfWriter) {
883        self.0.encode(output);
884        self.1.encode(output);
885        self.2.encode(output);
886    }
887}
888impl<A, B, C> Decodable for Triple<A, B, C>
889where
890    A: VarInt,
891    B: VarInt,
892    C: VarInt,
893{
894    fn decode(reader: &mut TdfReader) -> DecodeResult<Self> {
895        let a = A::decode(reader)?;
896        let b = B::decode(reader)?;
897        let c = C::decode(reader)?;
898        Ok((a, b, c))
899    }
900}
901
902impl<A, B, C> ValueType for Triple<A, B, C> {
903    fn value_type() -> TdfType {
904        TdfType::Triple
905    }
906}
907
908#[cfg(test)]
909mod test {
910
911    use std::time::Instant;
912
913    use crate::types::TdfMap;
914
915    /// Tests ordering a map
916    #[test]
917    fn test_map_ord() {
918        let mut map = TdfMap::<String, String>::new();
919
920        // Expected order:
921        // TdfMap {
922        //   "key1": "ABC"
923        //   "key11": "ABC"
924        //   "key17": "ABC"
925        //   "key2": "ABC"
926        //   "key24": "ABC"
927        //   "key4": "ABC"
928        // }
929
930        let i = Instant::now();
931        // Input order
932        map.insert("key1", "ABC");
933        map.insert("key2", "ABC");
934        map.insert("key4", "ABC");
935        map.insert("key24", "ABC");
936        map.insert("key11", "ABC");
937        map.insert("key17", "ABC");
938
939        map.order();
940        let el = i.elapsed();
941        println!("Full order time: {:?}", el);
942
943        assert_eq!(map.entries[0].key, "key1");
944        assert_eq!(map.entries[1].key, "key11");
945        assert_eq!(map.entries[2].key, "key17");
946        assert_eq!(map.entries[3].key, "key2");
947        assert_eq!(map.entries[4].key, "key24");
948        assert_eq!(map.entries[5].key, "key4");
949    }
950
951    /// Tests extending an existing map
952    #[test]
953    fn test_map_extend() {
954        let mut mapa = TdfMap::<String, String>::new();
955
956        mapa.insert("key1", "ABC");
957        mapa.insert("key2", "ABC");
958        mapa.insert("key4", "ABC");
959        mapa.insert("key24", "ABC");
960        mapa.insert("key11", "ABC");
961        mapa.insert("key17", "ABC");
962
963        let mut mapb = TdfMap::<String, String>::new();
964
965        mapb.insert("key1", "DDD");
966        mapb.insert("key2", "ABC");
967        mapb.insert("key4", "DDD");
968        mapb.insert("abc", "ABC");
969
970        mapa.extend(mapb);
971        println!("{mapa:?}")
972    }
973
974    /// Tests inserting into a map
975    #[test]
976    fn test_map_insert() {
977        let mut map = TdfMap::<String, String>::new();
978        map.insert("Test", "Abc");
979
980        let value = map.get("Test");
981
982        assert_eq!(value.unwrap(), "Abc");
983
984        println!("{value:?}")
985    }
986}