Skip to main content

bitcoin_consensus_encoding/encode/
encoders.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Collection of "standard encoders".
4//!
5//! These encoders should not be used directly. Instead, when implementing the
6//! [`super::Encodable`] trait on a type, you should define a newtype around one
7//! or more of these encoders, and pass through the [`Encoder`] implementation
8//! to your newtype. This avoids leaking encoding implementation details to the
9//! users of your type.
10//!
11//! For implementing these newtypes, we provide the [`encoder_newtype`] and
12//! [`encoder_newtype_exact`] macros.
13//!
14
15use internals::array_vec::ArrayVec;
16
17use super::{Encodable, Encoder, ExactSizeEncoder};
18
19/// The maximum length of a compact size encoding.
20const SIZE: usize = 9;
21
22/// An encoder for a single byte slice.
23pub struct BytesEncoder<'sl> {
24    sl: Option<&'sl [u8]>,
25}
26
27impl<'sl> BytesEncoder<'sl> {
28    /// Constructs a byte encoder which encodes the given byte slice, with no length prefix.
29    pub const fn without_length_prefix(sl: &'sl [u8]) -> Self { Self { sl: Some(sl) } }
30}
31
32impl Encoder for BytesEncoder<'_> {
33    fn current_chunk(&self) -> &[u8] { self.sl.unwrap_or_default() }
34
35    fn advance(&mut self) -> bool {
36        self.sl = None;
37        false
38    }
39}
40
41impl<'sl> ExactSizeEncoder for BytesEncoder<'sl> {
42    #[inline]
43    fn len(&self) -> usize { self.sl.map_or(0, <[u8]>::len) }
44}
45
46/// An encoder for a single array.
47pub struct ArrayEncoder<const N: usize> {
48    arr: Option<[u8; N]>,
49}
50
51impl<const N: usize> ArrayEncoder<N> {
52    /// Constructs an encoder which encodes the array with no length prefix.
53    pub const fn without_length_prefix(arr: [u8; N]) -> Self { Self { arr: Some(arr) } }
54}
55
56impl<const N: usize> Encoder for ArrayEncoder<N> {
57    #[inline]
58    fn current_chunk(&self) -> &[u8] { self.arr.as_ref().map(|x| &x[..]).unwrap_or_default() }
59
60    #[inline]
61    fn advance(&mut self) -> bool {
62        self.arr = None;
63        false
64    }
65}
66
67impl<const N: usize> ExactSizeEncoder for ArrayEncoder<N> {
68    #[inline]
69    fn len(&self) -> usize { self.arr.map_or(0, |a| a.len()) }
70}
71
72/// An encoder for a reference to an array.
73///
74/// This encoder borrows the array instead of taking ownership, avoiding a copy
75/// when the array is already available by reference (e.g., as a struct field).
76pub struct ArrayRefEncoder<'e, const N: usize> {
77    arr: Option<&'e [u8; N]>,
78}
79
80impl<'e, const N: usize> ArrayRefEncoder<'e, N> {
81    /// Constructs an encoder which encodes the array reference with no length prefix.
82    pub const fn without_length_prefix(arr: &'e [u8; N]) -> Self {
83        Self { arr: Some(arr) }
84    }
85}
86
87impl<const N: usize> Encoder for ArrayRefEncoder<'_, N> {
88    #[inline]
89    fn current_chunk(&self) -> &[u8] {
90        self.arr.map(|x| &x[..]).unwrap_or_default()
91    }
92
93    #[inline]
94    fn advance(&mut self) -> bool {
95        self.arr = None;
96        false
97    }
98}
99
100impl<const N: usize> ExactSizeEncoder for ArrayRefEncoder<'_, N> {
101    #[inline]
102    fn len(&self) -> usize {
103        self.arr.map_or(0, |a| a.len())
104    }
105}
106
107/// An encoder for a list of encodable types.
108pub struct SliceEncoder<'e, T: Encodable> {
109    /// The list of references to the objects we are encoding.
110    sl: &'e [T],
111    /// Encoder for the current object being encoded.
112    cur_enc: Option<T::Encoder<'e>>,
113}
114
115impl<'e, T: Encodable> SliceEncoder<'e, T> {
116    /// Constructs an encoder which encodes the slice _without_ adding the length prefix.
117    ///
118    /// To encode with a length prefix consider using the `Encoder2`.
119    ///
120    /// E.g, `Encoder2<CompactSizeEncoder, SliceEncoder<'e, Foo>>`.
121    pub fn without_length_prefix(sl: &'e [T]) -> Self {
122        // In this `map` call we cannot remove the closure. Seems to be a bug in the compiler.
123        // Perhaps https://github.com/rust-lang/rust/issues/102540 which is 3 years old with
124        // no replies or even an acknowledgement. We will not bother filing our own issue.
125        Self { sl, cur_enc: sl.first().map(|x| T::encoder(x)) }
126    }
127}
128
129impl<T: Encodable> Encoder for SliceEncoder<'_, T> {
130    fn current_chunk(&self) -> &[u8] {
131        // `advance` sets `cur_enc` to `None` once the slice encoder is completely exhausted.
132        self.cur_enc.as_ref().map(T::Encoder::current_chunk).unwrap_or_default()
133    }
134
135    fn advance(&mut self) -> bool {
136        let Some(cur) = self.cur_enc.as_mut() else {
137            return false;
138        };
139
140        loop {
141            // On subsequent calls, attempt to advance the current encoder and return
142            // success if this succeeds.
143            if cur.advance() {
144                return true;
145            }
146            // self.sl guaranteed to be non-empty if cur is non-None.
147            self.sl = &self.sl[1..];
148
149            // If advancing the current encoder failed, attempt to move to the next encoder.
150            if let Some(x) = self.sl.first() {
151                *cur = x.encoder();
152                if !cur.current_chunk().is_empty() {
153                    return true;
154                }
155            } else {
156                self.cur_enc = None; // shortcut the next call to advance()
157                return false;
158            }
159        }
160    }
161}
162
163/// An encoder which encodes two objects, one after the other.
164pub struct Encoder2<A, B> {
165    enc_idx: usize,
166    enc_1: A,
167    enc_2: B,
168}
169
170impl<A, B> Encoder2<A, B> {
171    /// Constructs a new composite encoder.
172    pub const fn new(enc_1: A, enc_2: B) -> Self { Self { enc_idx: 0, enc_1, enc_2 } }
173}
174
175impl<A: Encoder, B: Encoder> Encoder for Encoder2<A, B> {
176    #[inline]
177    fn current_chunk(&self) -> &[u8] {
178        if self.enc_idx == 0 {
179            self.enc_1.current_chunk()
180        } else {
181            self.enc_2.current_chunk()
182        }
183    }
184
185    #[inline]
186    fn advance(&mut self) -> bool {
187        if self.enc_idx == 0 {
188            if !self.enc_1.advance() {
189                self.enc_idx += 1;
190            }
191            true
192        } else {
193            self.enc_2.advance()
194        }
195    }
196}
197
198impl<A, B> ExactSizeEncoder for Encoder2<A, B>
199where
200    A: Encoder + ExactSizeEncoder,
201    B: Encoder + ExactSizeEncoder,
202{
203    #[inline]
204    fn len(&self) -> usize { self.enc_1.len() + self.enc_2.len() }
205}
206
207// For now we implement every higher encoder by composing Encoder2s, because
208// I'm lazy and this is trivial both to write and to review. For efficiency, we
209// should eventually unroll all of these. There are only a couple of them. The
210// unrolled versions should be macro-izable, if we want to do that.
211
212/// An encoder which encodes three objects, one after the other.
213pub struct Encoder3<A, B, C> {
214    inner: Encoder2<Encoder2<A, B>, C>,
215}
216
217impl<A, B, C> Encoder3<A, B, C> {
218    /// Constructs a new composite encoder.
219    pub const fn new(enc_1: A, enc_2: B, enc_3: C) -> Self {
220        Self { inner: Encoder2::new(Encoder2::new(enc_1, enc_2), enc_3) }
221    }
222}
223
224impl<A: Encoder, B: Encoder, C: Encoder> Encoder for Encoder3<A, B, C> {
225    #[inline]
226    fn current_chunk(&self) -> &[u8] { self.inner.current_chunk() }
227    #[inline]
228    fn advance(&mut self) -> bool { self.inner.advance() }
229}
230
231impl<A, B, C> ExactSizeEncoder for Encoder3<A, B, C>
232where
233    A: Encoder + ExactSizeEncoder,
234    B: Encoder + ExactSizeEncoder,
235    C: Encoder + ExactSizeEncoder,
236{
237    #[inline]
238    fn len(&self) -> usize { self.inner.len() }
239}
240
241/// An encoder which encodes four objects, one after the other.
242pub struct Encoder4<A, B, C, D> {
243    inner: Encoder2<Encoder2<A, B>, Encoder2<C, D>>,
244}
245
246impl<A, B, C, D> Encoder4<A, B, C, D> {
247    /// Constructs a new composite encoder.
248    pub const fn new(enc_1: A, enc_2: B, enc_3: C, enc_4: D) -> Self {
249        Self { inner: Encoder2::new(Encoder2::new(enc_1, enc_2), Encoder2::new(enc_3, enc_4)) }
250    }
251}
252
253impl<A: Encoder, B: Encoder, C: Encoder, D: Encoder> Encoder for Encoder4<A, B, C, D> {
254    #[inline]
255    fn current_chunk(&self) -> &[u8] { self.inner.current_chunk() }
256    #[inline]
257    fn advance(&mut self) -> bool { self.inner.advance() }
258}
259
260impl<A, B, C, D> ExactSizeEncoder for Encoder4<A, B, C, D>
261where
262    A: Encoder + ExactSizeEncoder,
263    B: Encoder + ExactSizeEncoder,
264    C: Encoder + ExactSizeEncoder,
265    D: Encoder + ExactSizeEncoder,
266{
267    #[inline]
268    fn len(&self) -> usize { self.inner.len() }
269}
270
271/// An encoder which encodes six objects, one after the other.
272pub struct Encoder6<A, B, C, D, E, F> {
273    inner: Encoder2<Encoder3<A, B, C>, Encoder3<D, E, F>>,
274}
275
276impl<A, B, C, D, E, F> Encoder6<A, B, C, D, E, F> {
277    /// Constructs a new composite encoder.
278    pub const fn new(enc_1: A, enc_2: B, enc_3: C, enc_4: D, enc_5: E, enc_6: F) -> Self {
279        Self {
280            inner: Encoder2::new(
281                Encoder3::new(enc_1, enc_2, enc_3),
282                Encoder3::new(enc_4, enc_5, enc_6),
283            ),
284        }
285    }
286}
287
288impl<A: Encoder, B: Encoder, C: Encoder, D: Encoder, E: Encoder, F: Encoder> Encoder
289    for Encoder6<A, B, C, D, E, F>
290{
291    #[inline]
292    fn current_chunk(&self) -> &[u8] { self.inner.current_chunk() }
293    #[inline]
294    fn advance(&mut self) -> bool { self.inner.advance() }
295}
296
297impl<A, B, C, D, E, F> ExactSizeEncoder for Encoder6<A, B, C, D, E, F>
298where
299    A: Encoder + ExactSizeEncoder,
300    B: Encoder + ExactSizeEncoder,
301    C: Encoder + ExactSizeEncoder,
302    D: Encoder + ExactSizeEncoder,
303    E: Encoder + ExactSizeEncoder,
304    F: Encoder + ExactSizeEncoder,
305{
306    #[inline]
307    fn len(&self) -> usize { self.inner.len() }
308}
309
310/// Encoder for a compact size encoded integer.
311pub struct CompactSizeEncoder {
312    buf: Option<ArrayVec<u8, SIZE>>,
313}
314
315impl CompactSizeEncoder {
316    /// Constructs a new `CompactSizeEncoder`.
317    ///
318    /// Encodings are defined only for the range of u64. On systems where usize is
319    /// larger than u64, it will be possible to call this method with out-of-range
320    /// values. In such cases we will ignore the passed value and encode [`u64::MAX`].
321    /// But even on such exotic systems, we expect users to pass the length of an
322    /// in-memory object, meaning that such large values are impossible to obtain.
323    pub fn new(value: usize) -> Self { Self { buf: Some(Self::encode(value)) } }
324
325    /// Returns the number of bytes used to encode this `CompactSize` value.
326    ///
327    /// # Returns
328    ///
329    /// - 1 for 0..=0xFC
330    /// - 3 for 0xFD..=(2^16-1)
331    /// - 5 for 0x10000..=(2^32-1)
332    /// - 9 otherwise.
333    #[inline]
334    pub const fn encoded_size(value: usize) -> usize {
335        match value {
336            0..=0xFC => 1,
337            0xFD..=0xFFFF => 3,
338            0x10000..=0xFFFF_FFFF => 5,
339            _ => 9,
340        }
341    }
342
343    /// Encodes `CompactSize` without allocating.
344    #[inline]
345    fn encode(value: usize) -> ArrayVec<u8, SIZE> {
346        let mut res = ArrayVec::<u8, SIZE>::new();
347        match value {
348            0..=0xFC => {
349                res.push(value as u8); // Cast ok because of match.
350            }
351            0xFD..=0xFFFF => {
352                let v = value as u16; // Cast ok because of match.
353                res.push(0xFD);
354                res.extend_from_slice(&v.to_le_bytes());
355            }
356            0x10000..=0xFFFF_FFFF => {
357                let v = value as u32; // Cast ok because of match.
358                res.push(0xFE);
359                res.extend_from_slice(&v.to_le_bytes());
360            }
361            _ => {
362                res.push(0xFF);
363                res.extend_from_slice(&value.to_le_bytes());
364            }
365        }
366        res
367    }
368}
369
370impl Encoder for CompactSizeEncoder {
371    #[inline]
372    fn current_chunk(&self) -> &[u8] { self.buf.as_ref().map(|b| &b[..]).unwrap_or_default() }
373
374    #[inline]
375    fn advance(&mut self) -> bool {
376        self.buf = None;
377        false
378    }
379}
380
381impl ExactSizeEncoder for CompactSizeEncoder {
382    #[inline]
383    fn len(&self) -> usize { self.buf.map_or(0, |buf| buf.len()) }
384}
385
386#[cfg(test)]
387mod tests {
388    use super::*;
389
390    struct TestBytes<'a>(&'a [u8]);
391
392    impl Encodable for TestBytes<'_> {
393        type Encoder<'e>
394            = BytesEncoder<'e>
395        where
396            Self: 'e;
397
398        fn encoder(&self) -> Self::Encoder<'_> { BytesEncoder::without_length_prefix(self.0) }
399    }
400
401    struct TestArray<const N: usize>([u8; N]);
402
403    impl<const N: usize> Encodable for TestArray<N> {
404        type Encoder<'e>
405            = ArrayEncoder<N>
406        where
407            Self: 'e;
408
409        fn encoder(&self) -> Self::Encoder<'_> { ArrayEncoder::without_length_prefix(self.0) }
410    }
411
412    #[test]
413    fn encode_array_with_data() {
414        // Should have one chunk with the array data, then exhausted.
415        let test_array = TestArray([1u8, 2, 3, 4]);
416        let mut encoder = test_array.encoder();
417        assert_eq!(encoder.len(), 4);
418        assert!(!encoder.is_empty());
419        assert_eq!(encoder.current_chunk(), &[1u8, 2, 3, 4][..]);
420        assert!(!encoder.advance());
421        assert!(encoder.current_chunk().is_empty());
422    }
423
424    #[test]
425    fn encode_empty_array() {
426        // Empty array should have one empty chunk, then exhausted.
427        let test_array = TestArray([]);
428        let mut encoder = test_array.encoder();
429        assert_eq!(encoder.len(), 0);
430        assert!(encoder.is_empty());
431        assert!(encoder.current_chunk().is_empty());
432        assert!(!encoder.advance());
433        assert!(encoder.current_chunk().is_empty());
434    }
435
436    #[test]
437    fn encode_array_ref_with_data() {
438        // Should have one chunk with the array data, then exhausted.
439        let data = [1u8, 2, 3, 4];
440        let mut encoder = ArrayRefEncoder::without_length_prefix(&data);
441        assert_eq!(encoder.len(), 4);
442        assert!(!encoder.is_empty());
443        assert_eq!(encoder.current_chunk(), &[1u8, 2, 3, 4][..]);
444        assert!(!encoder.advance());
445        assert!(encoder.current_chunk().is_empty());
446        assert_eq!(encoder.len(), 0);
447    }
448
449    #[test]
450    fn encode_empty_array_ref() {
451        // Empty array should have one empty chunk, then exhausted.
452        let data = [];
453        let mut encoder = ArrayRefEncoder::without_length_prefix(&data);
454        assert_eq!(encoder.len(), 0);
455        assert!(encoder.is_empty());
456        assert!(encoder.current_chunk().is_empty());
457        assert!(!encoder.advance());
458        assert!(encoder.current_chunk().is_empty());
459    }
460
461    #[test]
462    fn encode_byte_slice_without_prefix() {
463        // Should have one chunk with the byte data, then exhausted.
464        let obj = [1u8, 2, 3];
465        let test_bytes = TestBytes(&obj);
466        let mut encoder = test_bytes.encoder();
467
468        assert_eq!(encoder.len(), 3);
469        assert!(!encoder.is_empty());
470
471        assert_eq!(encoder.current_chunk(), &[1u8, 2, 3][..]);
472        assert!(!encoder.advance());
473        assert!(encoder.current_chunk().is_empty());
474    }
475
476    #[test]
477    fn encode_empty_byte_slice_without_prefix() {
478        // Should have one empty chunk, then exhausted.
479        let obj = [];
480        let test_bytes = TestBytes(&obj);
481        let mut encoder = test_bytes.encoder();
482
483        assert_eq!(encoder.len(), 0);
484        assert!(encoder.is_empty());
485
486        assert!(encoder.current_chunk().is_empty());
487        assert!(!encoder.advance());
488        assert!(encoder.current_chunk().is_empty());
489    }
490
491    #[test]
492    fn encode_slice_with_elements() {
493        // Should have the element chunks, then exhausted.
494        let slice = &[TestArray([0x34, 0x12, 0x00, 0x00]), TestArray([0x78, 0x56, 0x00, 0x00])];
495        let mut encoder = SliceEncoder::without_length_prefix(slice);
496
497        assert_eq!(encoder.current_chunk(), &[0x34, 0x12, 0x00, 0x00][..]);
498        assert!(encoder.advance());
499        assert_eq!(encoder.current_chunk(), &[0x78, 0x56, 0x00, 0x00][..]);
500        assert!(!encoder.advance());
501        assert!(encoder.current_chunk().is_empty());
502    }
503
504    #[test]
505    fn encode_empty_slice() {
506        // Should immediately be exhausted.
507        let slice: &[TestArray<4>] = &[];
508        let mut encoder = SliceEncoder::without_length_prefix(slice);
509
510        assert!(!encoder.advance());
511        assert!(encoder.current_chunk().is_empty());
512    }
513
514    #[test]
515    fn encode_slice_with_zero_sized_arrays() {
516        // Should have empty array chunks, then exhausted.
517        let slice = &[TestArray([]), TestArray([])];
518        let mut encoder = SliceEncoder::without_length_prefix(slice);
519
520        assert!(encoder.current_chunk().is_empty());
521        // The slice advanced is optimized to skip over empty chunks.
522        assert!(!encoder.advance());
523        assert!(encoder.current_chunk().is_empty());
524    }
525
526    #[test]
527    fn encode_two_arrays() {
528        // Should encode first array, then second array, then exhausted.
529        let enc1 = TestArray([1u8, 2]).encoder();
530        let enc2 = TestArray([3u8, 4]).encoder();
531        let mut encoder = Encoder2::new(enc1, enc2);
532
533        assert_eq!(encoder.len(), 4);
534        assert!(!encoder.is_empty());
535
536        assert_eq!(encoder.current_chunk(), &[1u8, 2][..]);
537        assert!(encoder.advance());
538        assert_eq!(encoder.current_chunk(), &[3u8, 4][..]);
539        assert!(!encoder.advance());
540        assert!(encoder.current_chunk().is_empty());
541    }
542
543    #[test]
544    fn encode_two_empty_arrays() {
545        // Should encode first empty array, then second empty array, then exhausted.
546        let enc1 = TestArray([]).encoder();
547        let enc2 = TestArray([]).encoder();
548        let mut encoder = Encoder2::new(enc1, enc2);
549
550        assert_eq!(encoder.len(), 0);
551        assert!(encoder.is_empty());
552
553        assert!(encoder.current_chunk().is_empty());
554        assert!(encoder.advance());
555        assert!(encoder.current_chunk().is_empty());
556        assert!(!encoder.advance());
557        assert!(encoder.current_chunk().is_empty());
558    }
559
560    #[test]
561    fn encode_three_arrays() {
562        // Should encode three arrays in sequence, then exhausted.
563        let enc1 = TestArray([1u8]).encoder();
564        let enc2 = TestArray([2u8, 3u8]).encoder();
565        let enc3 = TestArray([4u8, 5u8, 6u8]).encoder();
566        let mut encoder = Encoder3::new(enc1, enc2, enc3);
567
568        assert_eq!(encoder.len(), 6);
569        assert!(!encoder.is_empty());
570
571        assert_eq!(encoder.current_chunk(), &[1u8][..]);
572        assert!(encoder.advance());
573        assert_eq!(encoder.current_chunk(), &[2u8, 3u8][..]);
574        assert!(encoder.advance());
575        assert_eq!(encoder.current_chunk(), &[4u8, 5u8, 6u8][..]);
576        assert!(!encoder.advance());
577        assert!(encoder.current_chunk().is_empty());
578    }
579
580    #[test]
581    fn encode_four_arrays() {
582        // Should encode four arrays in sequence, then exhausted.
583        let enc1 = TestArray([0x10]).encoder();
584        let enc2 = TestArray([0x20]).encoder();
585        let enc3 = TestArray([0x30]).encoder();
586        let enc4 = TestArray([0x40]).encoder();
587        let mut encoder = Encoder4::new(enc1, enc2, enc3, enc4);
588
589        assert_eq!(encoder.len(), 4);
590        assert!(!encoder.is_empty());
591
592        assert_eq!(encoder.current_chunk(), &[0x10][..]);
593        assert!(encoder.advance());
594        assert_eq!(encoder.current_chunk(), &[0x20][..]);
595        assert!(encoder.advance());
596        assert_eq!(encoder.current_chunk(), &[0x30][..]);
597        assert!(encoder.advance());
598        assert_eq!(encoder.current_chunk(), &[0x40][..]);
599        assert!(!encoder.advance());
600        assert!(encoder.current_chunk().is_empty());
601    }
602
603    #[test]
604    fn encode_six_arrays() {
605        // Should encode six arrays in sequence, then exhausted.
606        let enc1 = TestArray([0x01]).encoder();
607        let enc2 = TestArray([0x02]).encoder();
608        let enc3 = TestArray([0x03]).encoder();
609        let enc4 = TestArray([0x04]).encoder();
610        let enc5 = TestArray([0x05]).encoder();
611        let enc6 = TestArray([0x06]).encoder();
612        let mut encoder = Encoder6::new(enc1, enc2, enc3, enc4, enc5, enc6);
613
614        assert_eq!(encoder.len(), 6);
615        assert!(!encoder.is_empty());
616
617        assert_eq!(encoder.current_chunk(), &[0x01][..]);
618        assert!(encoder.advance());
619        assert_eq!(encoder.current_chunk(), &[0x02][..]);
620        assert!(encoder.advance());
621        assert_eq!(encoder.current_chunk(), &[0x03][..]);
622        assert!(encoder.advance());
623        assert_eq!(encoder.current_chunk(), &[0x04][..]);
624        assert!(encoder.advance());
625        assert_eq!(encoder.current_chunk(), &[0x05][..]);
626        assert!(encoder.advance());
627        assert_eq!(encoder.current_chunk(), &[0x06][..]);
628        assert!(!encoder.advance());
629        assert!(encoder.current_chunk().is_empty());
630    }
631
632    #[test]
633    fn encode_mixed_composition_with_byte_slices() {
634        // Should encode byte slice, then array, then exhausted.
635        let enc1 = TestBytes(&[0xFF, 0xEE]).encoder();
636        let enc2 = TestArray([0xDD, 0xCC]).encoder();
637        let mut encoder = Encoder2::new(enc1, enc2);
638
639        assert_eq!(encoder.len(), 4);
640        assert!(!encoder.is_empty());
641
642        assert_eq!(encoder.current_chunk(), &[0xFF, 0xEE][..]);
643        assert!(encoder.advance());
644        assert_eq!(encoder.current_chunk(), &[0xDD, 0xCC][..]);
645        assert!(!encoder.advance());
646        assert!(encoder.current_chunk().is_empty());
647    }
648
649    #[test]
650    fn encode_nested_composition() {
651        // Should encode empty array, single byte array, then three byte array, then exhausted.
652        let enc1 = TestArray([]).encoder();
653        let enc2 = TestArray([0x42]).encoder();
654        let enc3 = TestArray([0x43, 0x44, 0x45]).encoder();
655        let mut encoder = Encoder3::new(enc1, enc2, enc3);
656
657        assert_eq!(encoder.len(), 4);
658        assert!(!encoder.is_empty());
659
660        assert!(encoder.current_chunk().is_empty());
661        assert!(encoder.advance());
662        assert_eq!(encoder.current_chunk(), &[0x42][..]);
663        assert!(encoder.advance());
664        assert_eq!(encoder.current_chunk(), &[0x43, 0x44, 0x45][..]);
665        assert!(!encoder.advance());
666        assert!(encoder.current_chunk().is_empty());
667    }
668
669    #[test]
670    fn encode_slice_with_array_composition() {
671        // Should encode slice elements, then array, then exhausted.
672        let slice = &[TestArray([0x10, 0x11]), TestArray([0x12, 0x13])];
673        let slice_enc = SliceEncoder::without_length_prefix(slice);
674        let array_enc = TestArray([0x20, 0x21]).encoder();
675        let mut encoder = Encoder2::new(slice_enc, array_enc);
676
677        assert_eq!(encoder.current_chunk(), &[0x10, 0x11][..]);
678        assert!(encoder.advance());
679        assert_eq!(encoder.current_chunk(), &[0x12, 0x13][..]);
680        assert!(encoder.advance());
681        assert_eq!(encoder.current_chunk(), &[0x20, 0x21][..]);
682        assert!(!encoder.advance());
683        assert!(encoder.current_chunk().is_empty());
684    }
685
686    #[test]
687    fn encode_array_with_slice_composition() {
688        // Should encode header array, then slice elements, then exhausted.
689        let header = TestArray([0xFF, 0xFE]).encoder();
690        let slice = &[TestArray([0x01]), TestArray([0x02]), TestArray([0x03])];
691        let slice_enc = SliceEncoder::without_length_prefix(slice);
692        let mut encoder = Encoder2::new(header, slice_enc);
693
694        assert_eq!(encoder.current_chunk(), &[0xFF, 0xFE][..]);
695        assert!(encoder.advance());
696        assert_eq!(encoder.current_chunk(), &[0x01][..]);
697        assert!(encoder.advance());
698        assert_eq!(encoder.current_chunk(), &[0x02][..]);
699        assert!(encoder.advance());
700        assert_eq!(encoder.current_chunk(), &[0x03][..]);
701        assert!(!encoder.advance());
702        assert!(encoder.current_chunk().is_empty());
703    }
704
705    #[test]
706    fn encode_multiple_slices_composition() {
707        // Should encode three slices in sequence, then exhausted.
708        let slice1 = &[TestArray([0xA1]), TestArray([0xA2])];
709        let slice2: &[TestArray<1>] = &[];
710        let slice3 = &[TestArray([0xC1]), TestArray([0xC2]), TestArray([0xC3])];
711
712        let enc1 = SliceEncoder::without_length_prefix(slice1);
713        let enc2 = SliceEncoder::without_length_prefix(slice2);
714        let enc3 = SliceEncoder::without_length_prefix(slice3);
715        let mut encoder = Encoder3::new(enc1, enc2, enc3);
716
717        assert_eq!(encoder.current_chunk(), &[0xA1][..]);
718        assert!(encoder.advance());
719        assert_eq!(encoder.current_chunk(), &[0xA2][..]);
720
721        // Skip the empty slice
722        assert!(encoder.advance());
723
724        assert!(encoder.advance());
725        assert_eq!(encoder.current_chunk(), &[0xC1][..]);
726        assert!(encoder.advance());
727        assert_eq!(encoder.current_chunk(), &[0xC2][..]);
728        assert!(encoder.advance());
729        assert_eq!(encoder.current_chunk(), &[0xC3][..]);
730        assert!(!encoder.advance());
731        assert!(encoder.current_chunk().is_empty());
732    }
733
734    #[test]
735    fn encode_complex_nested_structure() {
736        // Should encode header, slice with elements, and footer with prefix, then exhausted.
737        let header = TestBytes(&[0xDE, 0xAD]).encoder();
738        let data_slice = &[TestArray([0x01, 0x02]), TestArray([0x03, 0x04])];
739        let slice_enc = SliceEncoder::without_length_prefix(data_slice);
740        let footer = TestBytes(&[0xBE, 0xEF]).encoder();
741        let mut encoder = Encoder3::new(header, slice_enc, footer);
742
743        assert_eq!(encoder.current_chunk(), &[0xDE, 0xAD][..]);
744        assert!(encoder.advance());
745        assert_eq!(encoder.current_chunk(), &[0x01, 0x02][..]);
746        assert!(encoder.advance());
747        assert_eq!(encoder.current_chunk(), &[0x03, 0x04][..]);
748        assert!(encoder.advance());
749        assert_eq!(encoder.current_chunk(), &[0xBE, 0xEF][..]);
750        assert!(!encoder.advance());
751        assert!(encoder.current_chunk().is_empty());
752    }
753    #[test]
754    fn encode_compact_size() {
755        // 1-byte
756        let mut e = CompactSizeEncoder::new(0x10usize);
757        assert_eq!(e.current_chunk(), &[0x10][..]);
758        assert_eq!(e.len(), 1);
759        assert!(!e.advance());
760        assert!(e.current_chunk().is_empty());
761
762        let mut e = CompactSizeEncoder::new(0xFCusize);
763        assert_eq!(e.current_chunk(), &[0xFC][..]);
764        assert_eq!(e.len(), 1);
765        assert!(!e.advance());
766        assert!(e.current_chunk().is_empty());
767
768        // 0xFD + u16
769        let mut e = CompactSizeEncoder::new(0x00FDusize);
770        assert_eq!(e.current_chunk(), &[0xFD, 0xFD, 0x00][..]);
771        assert_eq!(e.len(), 3);
772        assert!(!e.advance());
773        assert!(e.current_chunk().is_empty());
774
775        let mut e = CompactSizeEncoder::new(0x0FFFusize);
776        assert_eq!(e.current_chunk(), &[0xFD, 0xFF, 0x0F][..]);
777        assert_eq!(e.len(), 3);
778        assert!(!e.advance());
779        assert!(e.current_chunk().is_empty());
780
781        // 0xFE + u32
782        let mut e = CompactSizeEncoder::new(0x0001_0000usize);
783        assert_eq!(e.current_chunk(), &[0xFE, 0x00, 0x00, 0x01, 0x00][..]);
784        assert_eq!(e.len(), 5);
785        assert!(!e.advance());
786        assert!(e.current_chunk().is_empty());
787
788        let mut e = CompactSizeEncoder::new(0x0F0F_0F0Fusize);
789        assert_eq!(e.current_chunk(), &[0xFE, 0x0F, 0x0F, 0x0F, 0x0F][..]);
790        assert_eq!(e.len(), 5);
791        assert!(!e.advance());
792        assert!(e.current_chunk().is_empty());
793
794        // 0xFF + u64
795        // This test only runs on systems with >= 64 bit usize.
796        if core::mem::size_of::<usize>() >= 8 {
797            let mut e = CompactSizeEncoder::new(0x0000_F0F0_F0F0_F0E0u64 as usize);
798            assert_eq!(
799                e.current_chunk(),
800                &[0xFF, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00][..]
801            );
802            assert_eq!(e.len(), 9);
803            assert!(!e.advance());
804            assert!(e.current_chunk().is_empty());
805        }
806
807        // > u64::MAX encodes as u64::MAX.
808        // This test only runs on systems with > 64 bit usize.
809        if core::mem::size_of::<usize>() > 8 {
810            let mut e = CompactSizeEncoder::new((u128::from(u64::MAX) + 5) as usize);
811            assert_eq!(
812                e.current_chunk(),
813                &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF][..]
814            );
815            assert_eq!(e.len(), 9);
816            assert!(!e.advance());
817            assert!(e.current_chunk().is_empty());
818        }
819    }
820
821    #[test]
822    fn encoded_value_1_byte() {
823        // Check lower bound, upper bound (and implicitly endian-ness).
824        for v in [0x00, 0x01, 0x02, 0xFA, 0xFB, 0xFC] {
825            let v = v as usize;
826            assert_eq!(CompactSizeEncoder::encoded_size(v), 1);
827            // Should be encoded as the value as a u8.
828            let want = [v as u8];
829            let got = CompactSizeEncoder::encode(v);
830            assert_eq!(got.as_slice().len(), 1); // sanity check
831            assert_eq!(got.as_slice(), want);
832        }
833    }
834
835    macro_rules! check_encode {
836        ($($test_name:ident, $size:expr, $value:expr, $want:expr);* $(;)?) => {
837            $(
838                #[test]
839                fn $test_name() {
840                    let value = $value as usize; // Because default integer type is i32.
841                    assert_eq!(CompactSizeEncoder::encoded_size(value), $size);
842                    let got = CompactSizeEncoder::encode(value);
843                    assert_eq!(got.as_slice().len(), $size); // sanity check
844                    assert_eq!(got.as_slice(), &$want);
845                }
846            )*
847        }
848    }
849
850    check_encode! {
851        // 3 byte encoding.
852        encoded_value_3_byte_lower_bound, 3, 0xFD, [0xFD, 0xFD, 0x00]; // 0x00FD
853        encoded_value_3_byte_endianness, 3, 0xABCD, [0xFD, 0xCD, 0xAB];
854        encoded_value_3_byte_upper_bound, 3, 0xFFFF, [0xFD, 0xFF, 0xFF];
855        // 5 byte encoding.
856        encoded_value_5_byte_lower_bound, 5, 0x0001_0000, [0xFE, 0x00, 0x00, 0x01, 0x00];
857        encoded_value_5_byte_endianness, 5, 0x0123_4567, [0xFE, 0x67, 0x45, 0x23, 0x01];
858        encoded_value_5_byte_upper_bound, 5, 0xFFFF_FFFF, [0xFE, 0xFF, 0xFF, 0xFF, 0xFF];
859    }
860
861    // Only test on platforms with a usize that is 64 bits
862    #[cfg(target_pointer_width = "64")]
863    check_encode! {
864        // 9 byte encoding.
865        encoded_value_9_byte_lower_bound, 9, 0x0000_0001_0000_0000, [0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00];
866        encoded_value_9_byte_endianness, 9, 0x0123_4567_89AB_CDEF, [0xFF, 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01];
867        encoded_value_9_byte_upper_bound, 9, u64::MAX, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
868    }
869
870    #[test]
871    fn iter_encoder() {
872        let test_array = TestArray([1u8, 2, 3, 4]);
873        let mut iter = crate::EncodableByteIter::new(&test_array);
874
875        assert_eq!(iter.len(), 4);
876
877        assert_eq!(iter.next().unwrap(), 1);
878        assert_eq!(iter.len(), 3);
879        assert_eq!(iter.next().unwrap(), 2);
880        assert_eq!(iter.len(), 2);
881        assert_eq!(iter.next().unwrap(), 3);
882        assert_eq!(iter.len(), 1);
883        assert_eq!(iter.next().unwrap(), 4);
884        assert_eq!(iter.len(), 0);
885        assert!(iter.next().is_none());
886    }
887}