1#![deny(missing_docs)]
2
3use std::io::{Read, Write};
26
27use tls_codec::{Deserialize, Serialize, Size};
28
29#[derive(Debug, thiserror::Error)]
31pub enum TlsMapError {
32 #[error("key already exists")]
34 KeyExists,
35 #[error("key not found")]
37 KeyNotFound,
38 #[error("tls codec error: {0}")]
40 Codec(#[from] tls_codec::Error),
41}
42
43#[derive(Clone, PartialEq, Eq)]
47pub struct TlsMapEntry<K, V> {
48 pub key: K,
50 pub value: V,
52}
53
54impl<K: std::fmt::Debug, V: std::fmt::Debug> std::fmt::Debug for TlsMapEntry<K, V> {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 write!(f, "{{ key: {:?}, value: {:?} }}", self.key, self.value)
57 }
58}
59
60impl<K: Size, V: Size> Size for TlsMapEntry<K, V> {
61 #[inline]
62 fn tls_serialized_len(&self) -> usize {
63 self.key.tls_serialized_len() + self.value.tls_serialized_len()
64 }
65}
66
67impl<K: Serialize, V: Serialize> Serialize for TlsMapEntry<K, V> {
68 #[inline]
69 fn tls_serialize<W: Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
70 let key_size = self.key.tls_serialize(writer)?;
71 let value_size = self.value.tls_serialize(writer)?;
72 Ok(key_size + value_size)
73 }
74}
75
76impl<K: Deserialize + Size, V: Deserialize + Size> Deserialize for TlsMapEntry<K, V> {
77 #[inline]
78 fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
79 where
80 Self: Sized,
81 {
82 let key = K::tls_deserialize(bytes)?;
83 let value = V::tls_deserialize(bytes)?;
84 Ok(Self { key, value })
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct TlsMap<K, V> {
115 entries: Vec<TlsMapEntry<K, V>>,
116}
117
118impl<K, V> Default for TlsMap<K, V> {
119 #[inline]
120 fn default() -> Self {
121 Self {
122 entries: Vec::new(),
123 }
124 }
125}
126
127impl<K, V> TlsMap<K, V>
128where
129 K: Ord + Eq,
130{
131 #[inline]
140 pub fn new() -> Self {
141 Self::default()
142 }
143
144 pub fn from_pairs(iter: impl IntoIterator<Item = (K, V)>) -> Self {
157 let entries = iter
158 .into_iter()
159 .collect::<std::collections::BTreeMap<K, V>>()
160 .into_iter()
161 .map(|(key, value)| TlsMapEntry { key, value })
162 .collect();
163 Self { entries }
164 }
165
166 #[inline]
176 pub fn insert(&mut self, key: K, value: V) -> Result<(), TlsMapError> {
177 match self.entries.binary_search_by(|e| e.key.cmp(&key)) {
178 Ok(_) => Err(TlsMapError::KeyExists),
179 Err(idx) => {
180 self.entries.insert(idx, TlsMapEntry { key, value });
181 Ok(())
182 }
183 }
184 }
185
186 #[inline]
198 pub fn update(&mut self, key: K, value: V) -> Result<(), TlsMapError> {
199 match self.entries.binary_search_by(|e| e.key.cmp(&key)) {
200 Ok(idx) => {
201 self.entries[idx].value = value;
202 Ok(())
203 }
204 Err(_) => Err(TlsMapError::KeyNotFound),
205 }
206 }
207
208 #[inline]
220 pub fn set(&mut self, key: K, value: V) {
221 match self.entries.binary_search_by(|e| e.key.cmp(&key)) {
222 Ok(idx) => self.entries[idx].value = value,
223 Err(idx) => self.entries.insert(idx, TlsMapEntry { key, value }),
224 }
225 }
226
227 #[inline]
238 pub fn remove(&mut self, key: &K) -> Result<V, TlsMapError> {
239 match self.entries.binary_search_by(|e| e.key.cmp(key)) {
240 Ok(idx) => Ok(self.entries.remove(idx).value),
241 Err(_) => Err(TlsMapError::KeyNotFound),
242 }
243 }
244
245 #[inline]
256 pub fn get(&self, key: &K) -> Option<&V> {
257 self.entries
258 .binary_search_by(|e| e.key.cmp(key))
259 .ok()
260 .map(|idx| &self.entries[idx].value)
261 }
262
263 #[inline]
274 pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
275 self.entries
276 .binary_search_by(|e| e.key.cmp(key))
277 .ok()
278 .map(|idx| &mut self.entries[idx].value)
279 }
280
281 #[inline]
283 pub fn contains_key(&self, key: &K) -> bool {
284 self.entries.binary_search_by(|e| e.key.cmp(key)).is_ok()
285 }
286
287 #[inline]
289 pub fn len(&self) -> usize {
290 self.entries.len()
291 }
292
293 #[inline]
295 pub fn is_empty(&self) -> bool {
296 self.entries.is_empty()
297 }
298
299 #[inline]
309 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
310 self.entries.iter().map(|e| (&e.key, &e.value))
311 }
312
313 #[inline]
315 pub fn keys(&self) -> impl Iterator<Item = &K> {
316 self.entries.iter().map(|e| &e.key)
317 }
318
319 #[inline]
321 pub fn values(&self) -> impl Iterator<Item = &V> {
322 self.entries.iter().map(|e| &e.value)
323 }
324}
325
326impl<K: Size, V: Size> Size for TlsMap<K, V> {
331 #[inline]
332 fn tls_serialized_len(&self) -> usize {
333 self.entries.tls_serialized_len()
334 }
335}
336
337impl<K: Serialize + Size + std::fmt::Debug, V: Serialize + Size + std::fmt::Debug> Serialize
338 for TlsMap<K, V>
339{
340 #[inline]
341 fn tls_serialize<W: Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
342 self.entries.tls_serialize(writer)
343 }
344}
345
346impl<K, V> Deserialize for TlsMap<K, V>
347where
348 K: Deserialize + Size + Ord + Eq,
349 V: Deserialize + Size,
350{
351 fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
353 where
354 Self: Sized,
355 {
356 let entries = Vec::<TlsMapEntry<K, V>>::tls_deserialize(bytes)?;
357
358 for [l, r] in entries.array_windows::<2>() {
360 if l.key >= r.key {
361 return Err(tls_codec::Error::DecodingError(
362 "TlsMap entries not sorted or contain duplicates".into(),
363 ));
364 }
365 }
366
367 Ok(Self { entries })
368 }
369}
370
371enum UndoAction<K, V> {
375 Remove(K),
377 Restore(K, V),
379 Insert(K, V),
381}
382
383#[derive(Debug, Clone, PartialEq, Eq)]
387pub enum TlsMapMutation<K, V> {
388 Insert {
390 key: K,
392 value: V,
394 },
395 Update {
397 key: K,
399 value: V,
401 },
402 Delete {
404 key: K,
406 },
407}
408
409#[derive(Debug, Clone, PartialEq, Eq)]
423pub struct TlsMapDelta<K, V> {
424 pub mutations: Vec<TlsMapMutation<K, V>>,
426}
427
428impl<K, V> TlsMapDelta<K, V> {
429 #[inline]
431 pub fn new() -> Self {
432 Self {
433 mutations: Vec::new(),
434 }
435 }
436
437 #[inline]
439 pub fn insert(mut self, key: K, value: V) -> Self {
440 self.mutations.push(TlsMapMutation::Insert { key, value });
441 self
442 }
443
444 #[inline]
446 pub fn update(mut self, key: K, value: V) -> Self {
447 self.mutations.push(TlsMapMutation::Update { key, value });
448 self
449 }
450
451 #[inline]
453 pub fn delete(mut self, key: K) -> Self {
454 self.mutations.push(TlsMapMutation::Delete { key });
455 self
456 }
457}
458
459impl<K, V> Default for TlsMapDelta<K, V> {
460 #[inline]
461 fn default() -> Self {
462 Self::new()
463 }
464}
465
466impl<K, V> TlsMap<K, V>
467where
468 K: Ord + Eq + Clone,
469{
470 pub fn apply_delta(&mut self, delta: TlsMapDelta<K, V>) -> Result<(), TlsMapError> {
489 let mut undo_stack: Vec<UndoAction<K, V>> = Vec::with_capacity(delta.mutations.len());
490
491 for mutation in delta.mutations {
492 match mutation {
493 TlsMapMutation::Insert { key, value } => {
494 if let Err(e) = self.insert(key.clone(), value) {
495 self.rollback(undo_stack);
496 return Err(e);
497 }
498 undo_stack.push(UndoAction::Remove(key));
499 }
500 TlsMapMutation::Update { key, mut value } => match self.get_mut(&key) {
501 Some(old) => {
502 std::mem::swap(old, &mut value);
503 undo_stack.push(UndoAction::Restore(key, value));
504 }
505 None => {
506 self.rollback(undo_stack);
507 return Err(TlsMapError::KeyNotFound);
508 }
509 },
510 TlsMapMutation::Delete { key } => match self.remove(&key) {
511 Ok(old) => {
512 undo_stack.push(UndoAction::Insert(key, old));
513 }
514 Err(e) => {
515 self.rollback(undo_stack);
516 return Err(e);
517 }
518 },
519 }
520 }
521
522 Ok(())
523 }
524
525 fn rollback(&mut self, undo_stack: Vec<UndoAction<K, V>>) {
527 for action in undo_stack.into_iter().rev() {
528 match action {
529 UndoAction::Remove(key) => {
530 let _ = self.remove(&key);
532 }
533 UndoAction::Restore(key, value) | UndoAction::Insert(key, value) => {
534 self.set(key, value);
535 }
536 }
537 }
538 }
539}
540
541impl<K: Size, V: Size> Size for TlsMapMutation<K, V> {
545 fn tls_serialized_len(&self) -> usize {
546 1 + match self {
547 Self::Insert { key, value } | Self::Update { key, value } => {
548 key.tls_serialized_len() + value.tls_serialized_len()
549 }
550 Self::Delete { key } => key.tls_serialized_len(),
551 }
552 }
553}
554
555impl<K: Serialize + Size, V: Serialize + Size> Serialize for TlsMapMutation<K, V> {
556 fn tls_serialize<W: Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
557 match self {
558 Self::Insert { key, value } => {
559 let mut written = 0u8.tls_serialize(writer)?;
560 written += key.tls_serialize(writer)?;
561 written += value.tls_serialize(writer)?;
562 Ok(written)
563 }
564 Self::Update { key, value } => {
565 let mut written = 1u8.tls_serialize(writer)?;
566 written += key.tls_serialize(writer)?;
567 written += value.tls_serialize(writer)?;
568 Ok(written)
569 }
570 Self::Delete { key } => {
571 let mut written = 2u8.tls_serialize(writer)?;
572 written += key.tls_serialize(writer)?;
573 Ok(written)
574 }
575 }
576 }
577}
578
579impl<K, V> Deserialize for TlsMapMutation<K, V>
580where
581 K: Deserialize + Size,
582 V: Deserialize + Size,
583{
584 fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
585 where
586 Self: Sized,
587 {
588 let tag = u8::tls_deserialize(bytes)?;
589 match tag {
590 0 => {
591 let key = K::tls_deserialize(bytes)?;
592 let value = V::tls_deserialize(bytes)?;
593 Ok(Self::Insert { key, value })
594 }
595 1 => {
596 let key = K::tls_deserialize(bytes)?;
597 let value = V::tls_deserialize(bytes)?;
598 Ok(Self::Update { key, value })
599 }
600 2 => {
601 let key = K::tls_deserialize(bytes)?;
602 Ok(Self::Delete { key })
603 }
604 _ => Err(tls_codec::Error::DecodingError(format!(
605 "unknown TlsMapMutation tag: {tag}"
606 ))),
607 }
608 }
609}
610
611impl<K: Size, V: Size> Size for TlsMapDelta<K, V> {
612 #[inline]
613 fn tls_serialized_len(&self) -> usize {
614 self.mutations.tls_serialized_len()
615 }
616}
617
618impl<K: Serialize + Size + std::fmt::Debug, V: Serialize + Size + std::fmt::Debug> Serialize
619 for TlsMapDelta<K, V>
620{
621 #[inline]
622 fn tls_serialize<W: Write>(&self, writer: &mut W) -> Result<usize, tls_codec::Error> {
623 self.mutations.tls_serialize(writer)
624 }
625}
626
627impl<K, V> Deserialize for TlsMapDelta<K, V>
628where
629 K: Deserialize + Size,
630 V: Deserialize + Size,
631{
632 fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, tls_codec::Error>
633 where
634 Self: Sized,
635 {
636 let mutations = Vec::<TlsMapMutation<K, V>>::tls_deserialize(bytes)?;
637 Ok(Self { mutations })
638 }
639}
640
641impl<K, V> IntoIterator for TlsMap<K, V> {
644 type Item = (K, V);
645 type IntoIter =
646 std::iter::Map<std::vec::IntoIter<TlsMapEntry<K, V>>, fn(TlsMapEntry<K, V>) -> (K, V)>;
647
648 #[inline]
649 fn into_iter(self) -> Self::IntoIter {
650 self.entries.into_iter().map(|e| (e.key, e.value))
651 }
652}
653
654impl<K: Ord + Eq, V> FromIterator<(K, V)> for TlsMap<K, V> {
655 #[inline]
656 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
657 Self::from_pairs(iter)
658 }
659}
660
661#[cfg(test)]
662mod tests {
663 use super::*;
664 use proptest::prelude::*;
665
666 fn build_map<K: Ord + Eq, V>(pairs: impl Iterator<Item = (K, V)>) -> TlsMap<K, V> {
670 pairs.collect()
671 }
672
673 macro_rules! tls_map_tests {
677 ($mod_name:ident, $K:ty, $V:ty, $n:expr, $mutate_v:expr) => {
678 mod $mod_name {
679 use super::*;
680
681 proptest! {
682 #[test]
683 fn round_trip(
684 pairs in proptest::collection::vec((any::<$K>(), any::<$V>()), 0..$n),
685 single_key in any::<$K>(),
686 single_value in any::<$V>(),
687 ) {
688 let map = build_map(pairs.clone().into_iter());
689 let bytes = map.tls_serialize_detached().expect("round trip serialization should succeed");
690 prop_assert_eq!(bytes.len(), map.tls_serialized_len(), "serialized size");
691 let deserialized =
692 TlsMap::<$K, $V>::tls_deserialize_exact(&bytes).expect("round trip deserialization should succeed");
693 prop_assert_eq!(map, deserialized);
694
695 let from_pairs = TlsMap::from_pairs(pairs.clone());
696 let collected = pairs.clone().into_iter().collect::<TlsMap<$K, $V>>();
697 let mut set_map = TlsMap::new();
698 for (key, value) in pairs {
699 set_map.set(key, value);
700 }
701 let canonical = from_pairs.tls_serialize_detached().unwrap();
702 prop_assert_eq!(&canonical, &collected.tls_serialize_detached().unwrap(), "collect encoding");
703 prop_assert_eq!(&canonical, &set_map.tls_serialize_detached().unwrap(), "set encoding");
704
705 let mut single = TlsMap::<$K, $V>::new();
706 single.insert(single_key, single_value).unwrap();
707 let single_bytes = single.tls_serialize_detached().unwrap();
708 prop_assert_eq!(single_bytes.len(), single.tls_serialized_len(), "single-entry size");
709 prop_assert_eq!(
710 single,
711 TlsMap::<$K, $V>::tls_deserialize_exact(&single_bytes).unwrap(),
712 "single-entry round trip"
713 );
714 prop_assert_eq!(TlsMap::<$K, $V>::new().tls_serialize_detached().unwrap(), vec![0], "empty encoding");
715 }
716
717 #[test]
718 fn insertion_order_irrelevant(
720 pairs in proptest::collection::hash_map(
721 any::<$K>(), any::<$V>(), 2..$n
722 )
723 ) {
724 let map_a = build_map(pairs.into_iter());
725 let map_b = build_map(map_a.clone().into_iter().rev());
726 prop_assert_eq!(
727 map_a.tls_serialize_detached().unwrap(),
728 map_b.tls_serialize_detached().unwrap()
729 );
730 }
731
732 #[test]
733 fn keys_always_sorted(
735 pairs in proptest::collection::vec((any::<$K>(), any::<$V>()), 0..$n)
736 ) {
737 let expected: std::collections::HashMap<$K, $V> = pairs.clone().into_iter().collect();
738 let map = build_map(pairs.into_iter());
739 let keys: Vec<&$K> = map.keys().collect();
740 for w in keys.array_windows::<2>() {
741 prop_assert!(w[0] < w[1]);
742 }
743 let borrowed: Vec<_> = map.iter().collect();
744 prop_assert_eq!(borrowed.len(), map.len(), "borrowed pairs");
745 for (key, value) in &borrowed {
746 prop_assert_eq!(expected.get(*key), Some(*value), "borrowed pair value");
747 }
748 prop_assert_eq!(map.values().collect::<Vec<_>>(), borrowed.iter().map(|(_, v)| *v).collect::<Vec<_>>(), "borrowed values");
749 let owned: Vec<_> = map.clone().into_iter().collect();
750 for w in owned.array_windows::<2>() {
751 prop_assert!(w[0].0 < w[1].0, "owned order");
752 }
753 prop_assert_eq!(owned.len(), borrowed.len(), "owned pairs");
754 for ((key, value), (borrowed_key, borrowed_value)) in owned.iter().zip(&borrowed) {
755 prop_assert_eq!(key, *borrowed_key, "owned key");
756 prop_assert_eq!(value, *borrowed_value, "owned value");
757 }
758 let mut one = TlsMap::<$K, $V>::new();
759 let key = <$K>::default();
760 let value = <$V>::default();
761 one.set(key.clone(), value.clone());
762 prop_assert_eq!(one.iter().collect::<Vec<_>>(), vec![(&key, &value)], "one borrowed pair");
763 prop_assert_eq!(one.values().collect::<Vec<_>>(), vec![&value], "one borrowed value");
764 }
765
766 #[test]
767 fn get_returns_inserted(
768 pairs in proptest::collection::vec((any::<$K>(), any::<$V>()), 1..$n)
769 ) {
770 let mut map = build_map(pairs.clone().into_iter());
771 let expected: std::collections::HashMap<$K, $V> = pairs
772 .into_iter()
773 .collect();
774 prop_assert_eq!(map.len(), expected.len());
775 for (k, v) in &expected {
776 prop_assert_eq!(map.get(k), Some(v));
777 let changed = ($mutate_v)(v.clone());
778 prop_assert!(matches!(map.insert(k.clone(), changed), Err(TlsMapError::KeyExists)), "duplicate insert");
779 }
780 let mut removed = map.clone();
781 for (k, v) in &expected {
782 prop_assert_eq!(&removed.remove(k).unwrap(), v, "remove returns value");
783 }
784 prop_assert!(removed.is_empty(), "all keys removed");
785 if let Some((key, value)) = expected.iter().next() {
786 let changed = ($mutate_v)(value.clone());
787 *map.get_mut(key).unwrap() = changed.clone();
788 prop_assert_eq!(map.get(key), Some(&changed), "mutable get");
789 }
790 }
791
792 #[test]
793 fn set_upsert(pairs in proptest::collection::vec((any::<$K>(), any::<$V>()), 1..$n)) {
794 let mut map = TlsMap::new();
795 let mut key_set = std::collections::BTreeSet::new();
796 for (k, v) in pairs {
797 key_set.insert(k.clone());
798 map.set(k.clone(), v.clone());
799 prop_assert_eq!(map.get(&k), Some(&v));
800 let v2 = ($mutate_v)(v);
801 map.set(k.clone(), v2.clone());
802 prop_assert_eq!(map.get(&k), Some(&v2));
803 prop_assert_eq!(map.len(), key_set.len());
804 }
805 }
806
807 #[test]
808 fn delta_rollback_on_failure(
810 pairs in proptest::collection::vec(
811 (any::<$K>(), any::<$V>()), 1..std::cmp::min($n, 200)
812 ),
813 bad_key: $K,
814 ) {
815 let mut map = build_map(pairs.into_iter());
816 let _ = map.remove(&bad_key);
817 prop_assume!(!map.is_empty());
818 let (known_key, old_value) = map.iter().next().unwrap();
819 let known_key = known_key.clone();
820 let changed_value = ($mutate_v)(old_value.clone());
821 let snapshot = map.clone();
822
823 let delta = TlsMapDelta::new()
824 .update(known_key, changed_value)
825 .update(bad_key, <$V>::default());
826 prop_assert!(map.apply_delta(delta).is_err());
827 prop_assert_eq!(map, snapshot);
828 }
829
830 #[test]
832 fn rejects_unsorted(
834 a in any::<$K>(),
835 b in any::<$K>(),
836 va in any::<$V>(),
837 vb in any::<$V>(),
838 ) {
839 if a >= b { return Ok(()); }
840 let mut content = Vec::new();
842 b.tls_serialize(&mut content).unwrap();
843 va.tls_serialize(&mut content).unwrap();
844 a.tls_serialize(&mut content).unwrap();
845 vb.tls_serialize(&mut content).unwrap();
846
847 let mut bytes = Vec::new();
848 tls_codec::vlen::write_length(&mut bytes, content.len()).unwrap();
849 bytes.extend_from_slice(&content);
850
851 prop_assert!(TlsMap::<$K, $V>::tls_deserialize_exact(&bytes).is_err());
852 }
853
854 #[test]
856 fn rejects_duplicates(
858 key in any::<$K>(),
859 va in any::<$V>(),
860 vb in any::<$V>(),
861 ) {
862 let mut content = Vec::new();
863 key.tls_serialize(&mut content).unwrap();
864 va.tls_serialize(&mut content).unwrap();
865 key.tls_serialize(&mut content).unwrap();
866 vb.tls_serialize(&mut content).unwrap();
867
868 let mut bytes = Vec::new();
869 tls_codec::vlen::write_length(&mut bytes, content.len()).unwrap();
870 bytes.extend_from_slice(&content);
871
872 prop_assert!(TlsMap::<$K, $V>::tls_deserialize_exact(&bytes).is_err());
873 }
874
875 #[test]
877 fn delta_apply_sequence(
879 existing in proptest::collection::hash_map(
880 any::<$K>(), any::<$V>(), 2..std::cmp::min($n, 50)
881 ),
882 new_entries in proptest::collection::hash_map(
883 any::<$K>(), any::<$V>(), 1..std::cmp::min($n, 50)
884 ),
885 updated_value in any::<$V>(),
886 ) {
887 let new_entries: std::collections::HashMap<_, _> = new_entries
888 .into_iter()
889 .filter(|(k, _)| !existing.contains_key(k))
890 .collect();
891 if new_entries.is_empty() { return Ok(()); }
892
893 let existing_keys: Vec<_> = existing.keys().cloned().collect();
895 let mid = existing_keys.len() / 2;
896 let (update_only, update_and_delete) = existing_keys.split_at(mid);
897 if update_only.is_empty() || update_and_delete.is_empty() { return Ok(()); }
898
899 let mut map: TlsMap<$K, $V> = existing.iter()
900 .map(|(k, v)| (k.clone(), v.clone()))
901 .collect();
902
903 let mut delta = TlsMapDelta::new();
904 for (k, v) in &new_entries {
905 delta = delta.insert(k.clone(), v.clone());
906 }
907 for k in &existing_keys {
908 delta = delta.update(k.clone(), updated_value.clone());
909 }
910 for k in update_and_delete {
911 delta = delta.delete(k.clone());
912 }
913
914 map.apply_delta(delta).unwrap();
915 prop_assert_eq!(map.len(), new_entries.len() + update_only.len());
916 for (k, v) in &new_entries {
917 prop_assert_eq!(map.get(k), Some(v));
918 }
919 for k in update_only {
920 prop_assert_eq!(map.get(k), Some(&updated_value));
921 }
922 for k in update_and_delete {
923 prop_assert!(!map.contains_key(k));
924 }
925 }
926
927 #[test]
929 fn nested_map_round_trip(
930 entries in proptest::collection::hash_map(
931 any::<u64>(),
932 proptest::collection::hash_map(
933 any::<$K>(), any::<$V>(), 0..std::cmp::min($n, 20)
934 ),
935 1..10
936 ),
937 reverse_entries in proptest::collection::hash_map(
938 any::<$K>(),
939 proptest::collection::hash_map(any::<u64>(), any::<$V>(), 0..20),
940 1..std::cmp::min($n, 10)
941 ),
942 ) {
943 let outer: TlsMap<u64, TlsMap<$K, $V>> = entries
944 .into_iter()
945 .map(|(k, inner)| (k, inner.into_iter().collect()))
946 .collect();
947 let bytes = outer.tls_serialize_detached().unwrap();
948 let deserialized = TlsMap::<u64, TlsMap<$K, $V>>::tls_deserialize_exact(&bytes).unwrap();
949 prop_assert_eq!(outer, deserialized, "u64 outer keys");
950
951 let reverse_outer: TlsMap<$K, TlsMap<u64, $V>> = reverse_entries
952 .into_iter()
953 .map(|(k, inner)| (k, inner.into_iter().collect()))
954 .collect();
955 let reverse_bytes = reverse_outer.tls_serialize_detached().unwrap();
956 let reverse_result = TlsMap::<$K, TlsMap<u64, $V>>::tls_deserialize_exact(&reverse_bytes).unwrap();
957 prop_assert_eq!(reverse_outer, reverse_result, "parameterized outer keys");
958 }
959
960 #[test]
962 fn delta_round_trip(
963 mutations in proptest::collection::vec(
964 (any::<$K>(), any::<$V>(), 0u8..3), 0..20
965 ),
966 key in any::<$K>(),
967 value in any::<$V>(),
968 ) {
969 let mut delta = TlsMapDelta::new();
970 for (key, value, tag) in mutations {
971 delta = match tag {
972 0 => delta.insert(key, value),
973 1 => delta.update(key, value),
974 _ => delta.delete(key),
975 };
976 }
977 let bytes = delta.tls_serialize_detached().unwrap();
978 let rt = TlsMapDelta::<$K, $V>::tls_deserialize_exact(&bytes).unwrap();
979 prop_assert_eq!(delta, rt);
980 for mutation in [
981 TlsMapMutation::Insert { key: key.clone(), value: value.clone() },
982 TlsMapMutation::Update { key: key.clone(), value: value.clone() },
983 TlsMapMutation::Delete { key: key.clone() },
984 ] {
985 let bytes = mutation.tls_serialize_detached().unwrap();
986 let decoded = TlsMapMutation::<$K, $V>::tls_deserialize_exact(&bytes).unwrap();
987 prop_assert_eq!(mutation, decoded, "mutation kind round trip");
988 }
989 let key_len = key.tls_serialized_len();
990 let mut key_only = Vec::new();
991 tls_codec::vlen::write_length(&mut key_only, 1 + key_len).unwrap();
992 3u8.tls_serialize(&mut key_only).unwrap();
993 key.tls_serialize(&mut key_only).unwrap();
994 prop_assert!(TlsMapDelta::<$K, $V>::tls_deserialize_exact(&key_only).is_err(), "invalid mutation tag with key only");
995
996 let mut key_and_value = Vec::new();
997 tls_codec::vlen::write_length(&mut key_and_value, 1 + key_len + value.tls_serialized_len()).unwrap();
998 3u8.tls_serialize(&mut key_and_value).unwrap();
999 key.tls_serialize(&mut key_and_value).unwrap();
1000 value.tls_serialize(&mut key_and_value).unwrap();
1001 prop_assert!(TlsMapDelta::<$K, $V>::tls_deserialize_exact(&key_and_value).is_err(), "invalid mutation tag with key and value");
1002 }
1003 }
1004 }
1005 };
1006 }
1007
1008 tls_map_tests!(u8_u8, u8, u8, 1000, |v: u8| v.wrapping_add(1));
1010 tls_map_tests!(u8_u16, u8, u16, 1000, |v: u16| v.wrapping_add(1));
1011 tls_map_tests!(u8_u32, u8, u32, 1000, |v: u32| v.wrapping_add(1));
1012 tls_map_tests!(u8_u64, u8, u64, 1000, |v: u64| v.wrapping_add(1));
1013 tls_map_tests!(u16_u8, u16, u8, 1000, |v: u8| v.wrapping_add(1));
1014 tls_map_tests!(u16_u16, u16, u16, 1000, |v: u16| v.wrapping_add(1));
1015 tls_map_tests!(u16_u32, u16, u32, 1000, |v: u32| v.wrapping_add(1));
1016 tls_map_tests!(u16_u64, u16, u64, 1000, |v: u64| v.wrapping_add(1));
1017 tls_map_tests!(u32_u8, u32, u8, 1000, |v: u8| v.wrapping_add(1));
1018 tls_map_tests!(u32_u16, u32, u16, 1000, |v: u16| v.wrapping_add(1));
1019 tls_map_tests!(u32_u32, u32, u32, 1000, |v: u32| v.wrapping_add(1));
1020 tls_map_tests!(u32_u64, u32, u64, 1000, |v: u64| v.wrapping_add(1));
1021 tls_map_tests!(u64_u8, u64, u8, 1000, |v: u8| v.wrapping_add(1));
1022 tls_map_tests!(u64_u16, u64, u16, 1000, |v: u16| v.wrapping_add(1));
1023 tls_map_tests!(u64_u32, u64, u32, 1000, |v: u32| v.wrapping_add(1));
1024 tls_map_tests!(u64_u64, u64, u64, 1000, |v: u64| v.wrapping_add(1));
1025 tls_map_tests!(u16_32_bytes, u16, [u8; 32], 1000, |v: [u8; 32]| {
1026 let mut v = v;
1027 v[0] = v[0].wrapping_add(1);
1028 v
1029 });
1030 tls_map_tests!(u64_vec, u64, Vec<u8>, 1000, |v: Vec<u8>| {
1031 let mut v = v;
1032 v.push(42);
1033 v
1034 });
1035 tls_map_tests!(_32_bytes_vec, [u8; 32], Vec<u8>, 1000, |v: Vec<u8>| {
1036 let mut v = v;
1037 v.push(1);
1038 v
1039 });
1040 tls_map_tests!(vec_vec, Vec<u8>, Vec<u8>, 1000, |v: Vec<u8>| {
1041 let mut v = v;
1042 v.push(2);
1043 v
1044 });
1045}