1use std::{
2 borrow::Cow,
3 collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque},
4 hash::Hash,
5 marker::PhantomData,
6};
7
8use bitvec::{boxed::BitBox, order::Msb0, slice::BitSlice, vec::BitVec, view::AsBits};
9
10use crate::{
11 Context,
12 r#as::{BorrowCow, Same},
13 de::{BitReader, BitReaderExt, BitUnpackAs},
14 ser::{BitPackAs, BitWriter, BitWriterExt},
15};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct NBits<const BITS: usize>;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct VarLen<As: ?Sized = Same, const BITS: usize = 32>(PhantomData<As>);
24
25impl<As: ?Sized, const BITS: usize> VarLen<As, BITS> {
26 #[inline]
27 fn pack_len_items<'a, W, T>(
28 source: &'a T,
29 writer: &mut W,
30 args: <<&'a As as IntoIterator>::Item as BitPackAs<<&'a T as IntoIterator>::Item>>::Args,
31 ) -> Result<(), W::Error>
32 where
33 W: BitWriter + ?Sized,
34 T: ?Sized,
35 &'a T: IntoIterator,
36 <&'a T as IntoIterator>::IntoIter: ExactSizeIterator,
37 &'a As: IntoIterator,
38 <&'a As as IntoIterator>::Item: BitPackAs<<&'a T as IntoIterator>::Item>,
39 <<&'a As as IntoIterator>::Item as BitPackAs<<&'a T as IntoIterator>::Item>>::Args: Clone,
40 {
41 let iter = source.into_iter();
42 writer
43 .pack_as::<_, NBits<BITS>>(iter.len(), ())
44 .context("length")?
45 .pack_many_as::<_, <&'a As as IntoIterator>::Item>(iter, args)?;
46 Ok(())
47 }
48
49 #[inline]
50 fn unpack_len_items<'de, R, T>(
51 reader: &mut R,
52 args: <As::Item as BitUnpackAs<'de, <T as IntoIterator>::Item>>::Args,
53 ) -> Result<T, R::Error>
54 where
55 R: BitReader<'de> + ?Sized,
56 T: IntoIterator + FromIterator<<T as IntoIterator>::Item>,
57 As: IntoIterator,
58 As::Item: BitUnpackAs<'de, <T as IntoIterator>::Item>,
59 <As::Item as BitUnpackAs<'de, <T as IntoIterator>::Item>>::Args: Clone,
60 {
61 let len: usize = reader.unpack_as::<_, NBits<BITS>>(()).context("length")?;
62 reader
63 .unpack_iter_as::<_, As::Item>(args)
64 .take(len)
65 .collect()
66 }
67}
68
69impl<const BITS: usize> BitPackAs<BitSlice<u8, Msb0>> for VarLen<Same, BITS> {
70 type Args = ();
71
72 #[inline]
73 fn pack_as<W>(
74 source: &BitSlice<u8, Msb0>,
75 writer: &mut W,
76 (): Self::Args,
77 ) -> Result<(), W::Error>
78 where
79 W: BitWriter + ?Sized,
80 {
81 writer
82 .pack_as::<_, NBits<BITS>>(source.len(), ())
83 .context("length")?
84 .write_bitslice(source)
85 }
86}
87
88impl<'a, const BITS: usize> BitPackAs<Cow<'a, BitSlice<u8, Msb0>>> for VarLen<Same, BITS> {
89 type Args = ();
90
91 #[inline]
92 fn pack_as<W>(
93 source: &Cow<'a, BitSlice<u8, Msb0>>,
94 writer: &mut W,
95 (): Self::Args,
96 ) -> Result<(), W::Error>
97 where
98 W: BitWriter + ?Sized,
99 {
100 writer.pack_as::<_, &Self>(source.as_ref(), ())?;
101 Ok(())
102 }
103}
104
105impl<const BITS: usize> BitPackAs<BitVec<u8, Msb0>> for VarLen<Same, BITS> {
106 type Args = ();
107
108 #[inline]
109 fn pack_as<W>(source: &BitVec<u8, Msb0>, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
110 where
111 W: BitWriter + ?Sized,
112 {
113 Self::pack_as(source.as_bitslice(), writer, ())
114 }
115}
116
117impl<const BITS: usize> BitPackAs<BitBox<u8, Msb0>> for VarLen<Same, BITS> {
118 type Args = ();
119
120 #[inline]
121 fn pack_as<W>(source: &BitBox<u8, Msb0>, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
122 where
123 W: BitWriter + ?Sized,
124 {
125 Self::pack_as(source.as_bitslice(), writer, ())
126 }
127}
128
129impl<'de: 'a, 'a, const BITS: usize> BitUnpackAs<'de, Cow<'a, BitSlice<u8, Msb0>>>
130 for VarLen<Same, BITS>
131{
132 type Args = ();
133
134 #[inline]
135 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<Cow<'a, BitSlice<u8, Msb0>>, R::Error>
136 where
137 R: BitReader<'de> + ?Sized,
138 {
139 let len = reader.unpack_as::<_, NBits<BITS>>(()).context("length")?;
140 reader.unpack_as::<_, BorrowCow>(len)
141 }
142}
143
144impl<'de, const BITS: usize> BitUnpackAs<'de, BitVec<u8, Msb0>> for VarLen<Same, BITS> {
145 type Args = ();
146
147 #[inline]
148 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<BitVec<u8, Msb0>, R::Error>
149 where
150 R: BitReader<'de> + ?Sized,
151 {
152 reader
153 .unpack_as::<Cow<BitSlice<u8, Msb0>>, Self>(())
154 .map(Cow::into_owned)
155 }
156}
157
158impl<'de, const BITS: usize> BitUnpackAs<'de, BitBox<u8, Msb0>> for VarLen<Same, BITS> {
159 type Args = ();
160
161 #[inline]
162 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<BitBox<u8, Msb0>, R::Error>
163 where
164 R: BitReader<'de> + ?Sized,
165 {
166 reader
167 .unpack_as::<BitVec<u8, Msb0>, Self>(())
168 .map(BitVec::into_boxed_bitslice)
169 }
170}
171
172impl<const BITS: usize> BitPackAs<[u8]> for VarLen<Same, BITS> {
173 type Args = ();
174
175 #[inline]
176 fn pack_as<W>(source: &[u8], writer: &mut W, (): Self::Args) -> Result<(), W::Error>
177 where
178 W: BitWriter + ?Sized,
179 {
180 writer
181 .pack_as::<_, NBits<BITS>>(source.len(), ())
182 .context("length")?
183 .write_bitslice(source.as_bits())
184 }
185}
186
187impl<'a, const BITS: usize> BitPackAs<Cow<'a, [u8]>> for VarLen<BorrowCow, BITS> {
188 type Args = ();
189
190 #[inline]
191 fn pack_as<W>(source: &Cow<'a, [u8]>, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
192 where
193 W: BitWriter + ?Sized,
194 {
195 writer.pack_as::<_, &VarLen<Same, BITS>>(source.as_ref(), ())?;
196 Ok(())
197 }
198}
199
200impl<'de: 'a, 'a, const BITS: usize> BitUnpackAs<'de, Cow<'a, [u8]>> for VarLen<BorrowCow, BITS> {
201 type Args = ();
202
203 #[inline]
204 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<Cow<'a, [u8]>, R::Error>
205 where
206 R: BitReader<'de> + ?Sized,
207 {
208 let len: usize = reader.unpack_as::<_, NBits<BITS>>(()).context("length")?;
209 reader.unpack_as::<_, BorrowCow>(len)
210 }
211}
212
213impl<const BITS: usize> BitPackAs<Vec<u8>> for VarLen<Same, BITS> {
214 type Args = ();
215
216 #[inline]
217 fn pack_as<W>(source: &Vec<u8>, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
218 where
219 W: BitWriter + ?Sized,
220 {
221 Self::pack_as(source.as_slice(), writer, ())
222 }
223}
224
225impl<'de, const BITS: usize> BitUnpackAs<'de, Vec<u8>> for VarLen<Same, BITS> {
226 type Args = ();
227
228 #[inline]
229 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<Vec<u8>, R::Error>
230 where
231 R: BitReader<'de> + ?Sized,
232 {
233 reader
234 .unpack_as::<Cow<[u8]>, VarLen<BorrowCow, BITS>>(())
235 .map(Cow::into_owned)
236 }
237}
238
239impl<T, As, const BITS: usize> BitPackAs<[T]> for VarLen<[As], BITS>
240where
241 As: BitPackAs<T>,
242 As::Args: Clone,
243{
244 type Args = As::Args;
246
247 #[inline]
248 fn pack_as<W>(source: &[T], writer: &mut W, args: Self::Args) -> Result<(), W::Error>
249 where
250 W: BitWriter + ?Sized,
251 {
252 Self::pack_len_items(source, writer, args)
253 }
254}
255
256impl<'a, T, As, const BITS: usize> BitPackAs<Cow<'a, [T]>> for VarLen<Cow<'a, [As]>, BITS>
257where
258 [T]: ToOwned,
259 [As]: ToOwned,
260 As: BitPackAs<T>,
261 As::Args: Clone,
262{
263 type Args = As::Args;
265
266 #[inline]
267 fn pack_as<W>(source: &Cow<'a, [T]>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
268 where
269 W: BitWriter + ?Sized,
270 {
271 VarLen::<[As], BITS>::pack_len_items(source.as_ref(), writer, args)
272 }
273}
274
275impl<'de: 'a, 'a, T, As, const BITS: usize> BitUnpackAs<'de, Cow<'a, [T]>>
276 for VarLen<Cow<'a, [As]>, BITS>
277where
278 [T]: ToOwned<Owned = Vec<T>>,
279 [As]: ToOwned<Owned = Vec<As>>,
280 As: BitUnpackAs<'de, T>,
281 As::Args: Clone,
282{
283 type Args = As::Args;
285
286 #[inline]
287 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Cow<'a, [T]>, R::Error>
288 where
289 R: BitReader<'de> + ?Sized,
290 {
291 VarLen::<Vec<As>, BITS>::unpack_len_items(reader, args).map(Cow::Owned)
292 }
293}
294
295impl<T, As, const BITS: usize> BitPackAs<Vec<T>> for VarLen<Vec<As>, BITS>
296where
297 As: BitPackAs<T>,
298 As::Args: Clone,
299{
300 type Args = As::Args;
302
303 #[inline]
304 fn pack_as<W>(source: &Vec<T>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
305 where
306 W: BitWriter + ?Sized,
307 {
308 Self::pack_len_items(source, writer, args)
309 }
310}
311
312impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, Vec<T>> for VarLen<Vec<As>, BITS>
313where
314 As: BitUnpackAs<'de, T>,
315 As::Args: Clone,
316{
317 type Args = As::Args;
319
320 #[inline]
321 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Vec<T>, R::Error>
322 where
323 R: BitReader<'de> + ?Sized,
324 {
325 Self::unpack_len_items(reader, args)
326 }
327}
328
329impl<T, As, const BITS: usize> BitPackAs<Box<[T]>> for VarLen<Box<[As]>, BITS>
330where
331 As: BitPackAs<T>,
332 As::Args: Clone,
333{
334 type Args = As::Args;
336
337 #[inline]
338 fn pack_as<W>(source: &Box<[T]>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
339 where
340 W: BitWriter + ?Sized,
341 {
342 Self::pack_len_items(source, writer, args)
343 }
344}
345
346impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, Box<[T]>> for VarLen<Box<[As]>, BITS>
347where
348 As: BitUnpackAs<'de, T>,
349 As::Args: Clone,
350{
351 type Args = As::Args;
353
354 #[inline]
355 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Box<[T]>, R::Error>
356 where
357 R: BitReader<'de> + ?Sized,
358 {
359 Self::unpack_len_items(reader, args)
360 }
361}
362
363impl<T, As, const BITS: usize> BitPackAs<VecDeque<T>> for VarLen<VecDeque<As>, BITS>
364where
365 As: BitPackAs<T>,
366 As::Args: Clone,
367{
368 type Args = As::Args;
370
371 #[inline]
372 fn pack_as<W>(source: &VecDeque<T>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
373 where
374 W: BitWriter + ?Sized,
375 {
376 Self::pack_len_items(source, writer, args)
377 }
378}
379
380impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, VecDeque<T>> for VarLen<VecDeque<As>, BITS>
381where
382 As: BitUnpackAs<'de, T>,
383 As::Args: Clone,
384{
385 type Args = As::Args;
387
388 #[inline]
389 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<VecDeque<T>, R::Error>
390 where
391 R: BitReader<'de> + ?Sized,
392 {
393 Self::unpack_len_items(reader, args)
394 }
395}
396
397impl<T, As, const BITS: usize> BitPackAs<LinkedList<T>> for VarLen<LinkedList<As>, BITS>
398where
399 As: BitPackAs<T>,
400 As::Args: Clone,
401{
402 type Args = As::Args;
404
405 #[inline]
406 fn pack_as<W>(source: &LinkedList<T>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
407 where
408 W: BitWriter + ?Sized,
409 {
410 Self::pack_len_items(source, writer, args)
411 }
412}
413
414impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, LinkedList<T>> for VarLen<LinkedList<As>, BITS>
415where
416 As: BitUnpackAs<'de, T>,
417 As::Args: Clone,
418{
419 type Args = As::Args;
421
422 #[inline]
423 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<LinkedList<T>, R::Error>
424 where
425 R: BitReader<'de> + ?Sized,
426 {
427 Self::unpack_len_items(reader, args)
428 }
429}
430
431impl<T, As, const BITS: usize> BitPackAs<BTreeSet<T>> for VarLen<BTreeSet<As>, BITS>
432where
433 As: BitPackAs<T>,
434 As::Args: Clone,
435{
436 type Args = As::Args;
438
439 #[inline]
440 fn pack_as<W>(source: &BTreeSet<T>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
441 where
442 W: BitWriter + ?Sized,
443 {
444 Self::pack_len_items(source, writer, args)
445 }
446}
447
448impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, BTreeSet<T>> for VarLen<BTreeSet<As>, BITS>
449where
450 T: Ord + Eq,
451 As: BitUnpackAs<'de, T>,
452 As::Args: Clone,
453{
454 type Args = As::Args;
456
457 #[inline]
458 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<BTreeSet<T>, R::Error>
459 where
460 R: BitReader<'de> + ?Sized,
461 {
462 Self::unpack_len_items(reader, args)
463 }
464}
465
466impl<K, V, KAs, VAs, const BITS: usize> BitPackAs<BTreeMap<K, V>>
467 for VarLen<BTreeMap<KAs, VAs>, BITS>
468where
469 KAs: BitPackAs<K>,
470 KAs::Args: Clone,
471 VAs: BitPackAs<V>,
472 VAs::Args: Clone,
473{
474 type Args = (KAs::Args, VAs::Args);
476
477 #[inline]
478 fn pack_as<W>(source: &BTreeMap<K, V>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
479 where
480 W: BitWriter + ?Sized,
481 {
482 Self::pack_len_items(source, writer, args)
483 }
484}
485
486impl<'de, K, V, KAs, VAs, const BITS: usize> BitUnpackAs<'de, BTreeMap<K, V>>
487 for VarLen<BTreeMap<KAs, VAs>, BITS>
488where
489 K: Ord + Eq,
490 KAs: BitUnpackAs<'de, K>,
491 KAs::Args: Clone,
492 VAs: BitUnpackAs<'de, V>,
493 VAs::Args: Clone,
494{
495 type Args = (KAs::Args, VAs::Args);
497
498 #[inline]
499 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<BTreeMap<K, V>, R::Error>
500 where
501 R: BitReader<'de> + ?Sized,
502 {
503 Self::unpack_len_items(reader, args)
504 }
505}
506
507impl<T, As, const BITS: usize> BitPackAs<HashSet<T>> for VarLen<HashSet<As>, BITS>
508where
509 As: BitPackAs<T>,
510 As::Args: Clone,
511{
512 type Args = As::Args;
514
515 #[inline]
516 fn pack_as<W>(source: &HashSet<T>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
517 where
518 W: BitWriter + ?Sized,
519 {
520 Self::pack_len_items(source, writer, args)
521 }
522}
523
524impl<'de, T, As, const BITS: usize> BitUnpackAs<'de, HashSet<T>> for VarLen<HashSet<As>, BITS>
525where
526 T: Hash + Eq,
527 As: BitUnpackAs<'de, T>,
528 As::Args: Clone,
529{
530 type Args = As::Args;
532
533 #[inline]
534 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<HashSet<T>, R::Error>
535 where
536 R: BitReader<'de> + ?Sized,
537 {
538 Self::unpack_len_items(reader, args)
539 }
540}
541
542impl<K, V, KAs, VAs, const BITS: usize> BitPackAs<HashMap<K, V>> for VarLen<HashMap<KAs, VAs>, BITS>
543where
544 KAs: BitPackAs<K>,
545 KAs::Args: Clone,
546 VAs: BitPackAs<V>,
547 VAs::Args: Clone,
548{
549 type Args = (KAs::Args, VAs::Args);
551
552 #[inline]
553 fn pack_as<W>(source: &HashMap<K, V>, writer: &mut W, args: Self::Args) -> Result<(), W::Error>
554 where
555 W: BitWriter + ?Sized,
556 {
557 Self::pack_len_items(source, writer, args)
558 }
559}
560
561impl<'de, K, V, KAs, VAs, const BITS: usize> BitUnpackAs<'de, HashMap<K, V>>
562 for VarLen<HashMap<KAs, VAs>, BITS>
563where
564 K: Hash + Eq,
565 KAs: BitUnpackAs<'de, K>,
566 KAs::Args: Clone,
567 VAs: BitUnpackAs<'de, V>,
568 VAs::Args: Clone,
569{
570 type Args = (KAs::Args, VAs::Args);
572
573 #[inline]
574 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<HashMap<K, V>, R::Error>
575 where
576 R: BitReader<'de> + ?Sized,
577 {
578 Self::unpack_len_items(reader, args)
579 }
580}
581
582impl<const BITS: usize> BitPackAs<str> for VarLen<Same, BITS> {
583 type Args = ();
584
585 #[inline]
586 fn pack_as<W>(source: &str, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
587 where
588 W: BitWriter + ?Sized,
589 {
590 writer.pack_as::<_, &Self>(source.as_bytes(), ())?;
591 Ok(())
592 }
593}
594
595impl<'a, const BITS: usize> BitPackAs<Cow<'a, str>> for VarLen<Same, BITS> {
596 type Args = ();
597
598 #[inline]
599 fn pack_as<W>(source: &Cow<'a, str>, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
600 where
601 W: BitWriter + ?Sized,
602 {
603 writer.pack_as::<_, &Self>(source.as_ref(), ())?;
604 Ok(())
605 }
606}
607
608impl<'de: 'a, 'a, const BITS: usize> BitUnpackAs<'de, Cow<'a, str>> for VarLen<Same, BITS> {
609 type Args = ();
610
611 #[inline]
612 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<Cow<'a, str>, R::Error>
613 where
614 R: BitReader<'de> + ?Sized,
615 {
616 let len: usize = reader.unpack_as::<_, NBits<BITS>>(()).context("length")?;
617 reader.unpack_as::<_, BorrowCow>(len)
618 }
619}
620
621impl<const BITS: usize> BitPackAs<String> for VarLen<Same, BITS> {
622 type Args = ();
623
624 #[inline]
625 fn pack_as<W>(source: &String, writer: &mut W, (): Self::Args) -> Result<(), W::Error>
626 where
627 W: BitWriter + ?Sized,
628 {
629 writer.pack_as::<_, &Self>(source.as_str(), ())?;
630 Ok(())
631 }
632}
633
634impl<'de, const BITS: usize> BitUnpackAs<'de, String> for VarLen<Same, BITS> {
635 type Args = ();
636
637 #[inline]
638 fn unpack_as<R>(reader: &mut R, (): Self::Args) -> Result<String, R::Error>
639 where
640 R: BitReader<'de> + ?Sized,
641 {
642 reader.unpack_as::<Cow<str>, Self>(()).map(Cow::into_owned)
643 }
644}
645
646#[cfg(test)]
647mod tests {
648 use std::fmt::Debug;
649
650 use bitvec::bitvec;
651 use rstest::rstest;
652
653 use crate::{NoArgs, de::BitUnpack, ser::BitPack, tests::assert_pack_unpack_as_eq};
654
655 use super::*;
656
657 #[rstest]
658 #[case(bitvec![u8, Msb0;])]
659 #[case(bitvec![u8, Msb0; 1, 1, 0, 0, 1])]
660 #[case(Vec::<u8>::new())]
661 #[case(vec![1, 2, 3])]
662 fn roundtrip<T>(#[case] value: T)
663 where
664 for<'de> VarLen: BitPackAs<T, Args = ()> + BitUnpackAs<'de, T, Args = ()>,
665 T: PartialEq + Debug,
666 {
667 assert_pack_unpack_as_eq::<_, VarLen>(value, ());
668 }
669
670 #[rstest]
671 #[case(BTreeSet::<u8>::new())]
672 #[case(BTreeSet::from([1, 2, 3]))]
673 fn roundtrip_btreeset<T>(#[case] value: BTreeSet<T>)
674 where
675 T: BitPack<Args = ()> + Ord + Eq + Debug,
676 for<'de> T: BitUnpack<'de, Args = ()>,
677 {
678 assert_pack_unpack_as_eq::<_, VarLen<BTreeSet<Same>>>(value, ());
679 }
680
681 #[rstest]
682 #[case(BTreeMap::<u8, u8>::new())]
683 #[case(BTreeMap::from_iter([(1, 1), (2,2), (3,3)]))]
684 fn roundtrip_btreemap<K, V>(#[case] value: BTreeMap<K, V>)
685 where
686 for<'de> K: BitPack<Args = ()> + BitUnpack<'de, Args = ()> + Ord + Eq + Debug,
687 for<'de> V: BitPack<Args = ()> + BitUnpack<'de, Args = ()> + PartialEq + Debug,
688 {
689 #[allow(clippy::zero_sized_map_values)]
690 assert_pack_unpack_as_eq::<_, VarLen<BTreeMap<Same, Same>>>(value, NoArgs::EMPTY);
691 }
692
693 #[rstest]
694 #[case(HashSet::<u8>::new())]
695 #[case(HashSet::from([1, 2, 3]))]
696 fn roundtrip_hashset<T>(#[case] value: HashSet<T>)
697 where
698 T: BitPack<Args = ()> + Hash + Eq + Debug,
699 for<'de> T: BitUnpack<'de, Args = ()>,
700 {
701 assert_pack_unpack_as_eq::<_, VarLen<HashSet<Same>>>(value, ());
702 }
703
704 #[rstest]
705 #[case(HashMap::<u8, u8>::new())]
706 #[case(HashMap::from_iter([(1, 1), (2,2), (3,3)]))]
707 fn roundtrip_hashmap<K, V>(#[case] value: HashMap<K, V>)
708 where
709 for<'de> K: BitPack<Args = ()> + BitUnpack<'de, Args = ()> + Hash + Eq + Debug,
710 for<'de> V: BitPack<Args = ()> + BitUnpack<'de, Args = ()> + PartialEq + Debug,
711 {
712 #[allow(clippy::zero_sized_map_values)]
713 assert_pack_unpack_as_eq::<_, VarLen<HashMap<Same, Same>>>(value, NoArgs::EMPTY);
714 }
715}