bitstream_io/
lib.rs

1// Copyright 2017 Brian Langenberger
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Traits and helpers for bitstream handling functionality
10//!
11//! Bitstream readers are for reading signed and unsigned integer
12//! values from a stream whose sizes may not be whole bytes.
13//! Bitstream writers are for writing signed and unsigned integer
14//! values to a stream, also potentially un-aligned at a whole byte.
15//!
16//! Both big-endian and little-endian streams are supported.
17//!
18//! The only requirement for wrapped reader streams is that they must
19//! implement the [`io::Read`] trait, and the only requirement
20//! for writer streams is that they must implement the [`io::Write`] trait.
21//!
22//! In addition, reader streams do not consume any more bytes
23//! from the underlying reader than necessary, buffering only a
24//! single partial byte as needed.
25//! Writer streams also write out all whole bytes as they are accumulated.
26//!
27//! Readers and writers are also designed to work with integer
28//! types of any possible size.
29//! Many of Rust's built-in integer types are supported by default.
30
31//! # Minimum Compiler Version
32//!
33//! Beginning with version 2.4, the minimum compiler version has been
34//! updated to Rust 1.79.
35//!
36//! The issue is that reading an excessive number of
37//! bits to a type which is too small to hold them,
38//! or writing an excessive number of bits from too small of a type,
39//! are always errors:
40//! ```
41//! use std::io::{Read, Cursor};
42//! use bitstream_io::{BigEndian, BitReader, BitRead};
43//! let data = [0; 10];
44//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
45//! let x: Result<u32, _> = r.read_var(64);  // reading 64 bits to u32 always fails at runtime
46//! assert!(x.is_err());
47//! ```
48//! but those errors will not be caught until the program runs,
49//! which is less than ideal for the common case in which
50//! the number of bits is already known at compile-time.
51//!
52//! But starting with Rust 1.79, we can now have read and write methods
53//! which take a constant number of bits and can validate the number of bits
54//! are small enough for the type being read/written at compile-time:
55//! ```rust,compile_fail
56//! use std::io::{Read, Cursor};
57//! use bitstream_io::{BigEndian, BitReader, BitRead};
58//! let data = [0; 10];
59//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
60//! let x: Result<u32, _> = r.read::<64, _>();  // doesn't compile at all
61//! ```
62//! Since catching potential bugs at compile-time is preferable
63//! to encountering errors at runtime, this will hopefully be
64//! an improvement in the long run.
65
66//! # Changes From 3.X.X
67//!
68//! Version 4.0.0 features significant optimizations to the [`BitRecorder`]
69//! and deprecates the [`BitCounter`] in favor of [`BitsWritten`],
70//! which no longer requires specifying an endianness.
71//!
72//! In addition, the [`BitRead::read_bytes`] and [`BitWrite::write_bytes`]
73//! methods are significantly optimized in the case of non-aligned
74//! reads and writes.
75//!
76//! Finally, the [`Endianness`] traits have been sealed so as not
77//! to be implemented by other packages.  Given that other endianness
78//! types are extremely rare in file formats and end users should not
79//! have to implement this trait themselves, this should not be a
80//! concern.
81//!
82//! # Changes From 2.X.X
83//!
84//! Version 3.0.0 has made many breaking changes to the [`BitRead`] and
85//! [`BitWrite`] traits.
86//!
87//! The [`BitRead::read`] method takes a constant number of bits,
88//! and the [`BitRead::read_var`] method takes a variable number of bits
89//! (reversing the older [`BitRead2::read_in`] and [`BitRead2::read`]
90//! calling methods to emphasize using the constant-based one,
91//! which can do more validation at compile-time).
92//! A new [`BitRead2`] trait uses the older calling convention
93//! for compatibility with existing code and is available
94//! for anything implementing [`BitRead`].
95//!
96//! In addition, the main reading methods return primitive types which
97//! implement a new [`Integer`] trait,
98//! which delegates to [`BitRead::read_unsigned`]
99//! or [`BitRead::read_signed`] depending on whether the output
100//! is an unsigned or signed type.
101//!
102//! [`BitWrite::write`] and [`BitWrite::write_var`] work
103//! similarly to the reader's `read` methods, taking anything
104//! that implements [`Integer`] and writing an unsigned or
105//! signed value to [`BitWrite::write_unsigned`] or
106//! [`BitWrite::write_signed`] as appropriate.
107//!
108//! And as with reading, a [`BitWrite2`] trait is offered
109//! for compatibility.
110//!
111//! In addition, the Huffman code handling has been rewritten
112//! to use a small amount of macro magic to write
113//! code to read and write symbols at compile-time.
114//! This is significantly faster than the older version
115//! and can no longer fail to compile at runtime.
116//!
117//! Lastly, there's a new [`BitCount`] struct which wraps a humble
118//! `u32` but encodes the maximum possible number of bits
119//! at the type level.
120//! This is intended for file formats which encode the number
121//! of bits to be read in the format itself.
122//! For example, FLAC's predictor coefficient precision
123//! is a 4 bit value which indicates how large each predictor
124//! coefficient is in bits
125//! (each coefficient might be an `i32` type).
126//! By keeping track of the maximum value at compile time
127//! (4 bits' worth, in this case), we can eliminate
128//! any need to check that coefficients aren't too large
129//! for an `i32` at runtime.
130//! This is accomplished by using [`BitRead::read_count`] to
131//! read a [`BitCount`] and then reading final values with
132//! that number of bits using [`BitRead::read_counted`].
133
134//! # Migrating From Pre 1.0.0
135//!
136//! There are now [`BitRead`] and [`BitWrite`] traits for bitstream
137//! reading and writing (analogous to the standard library's
138//! `Read` and `Write` traits) which you will also need to import.
139//! The upside to this approach is that library consumers
140//! can now make functions and methods generic over any sort
141//! of bit reader or bit writer, regardless of the underlying
142//! stream byte source or endianness.
143
144#![cfg_attr(docsrs, feature(doc_cfg))]
145#![warn(missing_docs)]
146#![forbid(unsafe_code)]
147#![no_std]
148
149#[cfg(feature = "alloc")]
150extern crate alloc;
151#[cfg(feature = "std")]
152extern crate std;
153
154#[cfg(not(feature = "std"))]
155use core2::io;
156
157use core::convert::TryInto;
158use core::num::NonZero;
159use core::ops::{
160    BitAnd, BitOr, BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
161};
162use core::{fmt::Debug, marker::PhantomData, mem};
163#[cfg(feature = "std")]
164use std::io;
165
166pub mod huffman;
167pub mod read;
168pub mod write;
169pub use read::{
170    BitRead, BitRead2, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamUsing,
171    FromBitStreamWith, FromByteStream, FromByteStreamUsing, FromByteStreamWith,
172};
173#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
174#[cfg(feature = "alloc")]
175pub use write::BitRecorder;
176pub use write::{
177    BitWrite, BitWrite2, BitWriter, BitsWritten, ByteWrite, ByteWriter, ToBitStream,
178    ToBitStreamUsing, ToBitStreamWith, ToByteStream, ToByteStreamUsing, ToByteStreamWith,
179};
180
181#[allow(deprecated)]
182pub use write::BitCounter;
183
184/// A trait intended for simple fixed-length primitives (such as ints and floats)
185/// which allows them to be read and written to streams of
186/// different endiannesses verbatim.
187pub trait Primitive {
188    /// The raw byte representation of this numeric type
189    type Bytes: AsRef<[u8]> + AsMut<[u8]>;
190
191    /// An empty buffer of this type's size
192    fn buffer() -> Self::Bytes;
193
194    /// Our value in big-endian bytes
195    fn to_be_bytes(self) -> Self::Bytes;
196
197    /// Our value in little-endian bytes
198    fn to_le_bytes(self) -> Self::Bytes;
199
200    /// Convert big-endian bytes to our value
201    fn from_be_bytes(bytes: Self::Bytes) -> Self;
202
203    /// Convert little-endian bytes to our value
204    fn from_le_bytes(bytes: Self::Bytes) -> Self;
205}
206
207macro_rules! define_primitive_numeric {
208    ($t:ty) => {
209        impl Primitive for $t {
210            type Bytes = [u8; mem::size_of::<$t>()];
211
212            #[inline(always)]
213            fn buffer() -> Self::Bytes {
214                [0; mem::size_of::<$t>()]
215            }
216            #[inline(always)]
217            fn to_be_bytes(self) -> Self::Bytes {
218                self.to_be_bytes()
219            }
220            #[inline(always)]
221            fn to_le_bytes(self) -> Self::Bytes {
222                self.to_le_bytes()
223            }
224            #[inline(always)]
225            fn from_be_bytes(bytes: Self::Bytes) -> Self {
226                <$t>::from_be_bytes(bytes)
227            }
228            #[inline(always)]
229            fn from_le_bytes(bytes: Self::Bytes) -> Self {
230                <$t>::from_le_bytes(bytes)
231            }
232        }
233    };
234}
235
236impl<const N: usize> Primitive for [u8; N] {
237    type Bytes = [u8; N];
238
239    #[inline(always)]
240    fn buffer() -> Self::Bytes {
241        [0; N]
242    }
243
244    #[inline(always)]
245    fn to_be_bytes(self) -> Self::Bytes {
246        self
247    }
248
249    #[inline(always)]
250    fn to_le_bytes(self) -> Self::Bytes {
251        self
252    }
253
254    #[inline(always)]
255    fn from_be_bytes(bytes: Self::Bytes) -> Self {
256        bytes
257    }
258
259    #[inline(always)]
260    fn from_le_bytes(bytes: Self::Bytes) -> Self {
261        bytes
262    }
263}
264
265/// This trait is for integer types which can be read or written
266/// to a bit stream as a partial amount of bits.
267///
268/// It unifies signed and unsigned integer types by delegating
269/// reads and writes to the signed and unsigned reading
270/// and writing methods as appropriate.
271pub trait Integer {
272    /// Reads a value of ourself from the stream
273    /// with the given number of bits.
274    ///
275    /// # Errors
276    ///
277    /// Passes along any I/O error from the underlying stream.
278    /// A compile-time error occurs if the given number of bits
279    /// is larger than our type.
280    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
281    where
282        Self: Sized;
283
284    /// Reads a value of ourself from the stream
285    /// with the given number of bits.
286    ///
287    /// # Errors
288    ///
289    /// Passes along any I/O error from the underlying stream.
290    /// Also returns an error if our type is too small
291    /// to hold the requested number of bits.
292    fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
293    where
294        R: BitRead + ?Sized,
295        Self: Sized;
296
297    /// Writes ourself to the stream using the given const number of bits.
298    ///
299    /// # Errors
300    ///
301    /// Passes along any I/O error from the underlying stream.
302    /// Returns an error if our value is too large
303    /// to fit the given number of bits.
304    /// A compile-time error occurs if the given number of bits
305    /// is larger than our type.
306    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()>;
307
308    /// Writes ourself to the stream using the given number of bits.
309    ///
310    /// # Errors
311    ///
312    /// Passes along any I/O error from the underlying stream.
313    /// Returns an error if our value is too small
314    /// to hold the given number of bits.
315    /// Returns an error if our value is too large
316    /// to fit the given number of bits.
317    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
318        self,
319        writer: &mut W,
320        bits: BitCount<MAX>,
321    ) -> io::Result<()>;
322}
323
324/// This trait is for integer types which can be read or written
325/// to a bit stream as variable-width integers.
326///
327/// It unifies signed and unsigned integer types by delegating
328/// reads and write to the signed and unsigned vbr reading and
329/// writing methods as appropriate.
330pub trait VBRInteger: Integer {
331    /// Reads a value of ourself from the stream using a variable width integer.
332    ///
333    /// # Errors
334    ///
335    /// Passes along any I/O error from the underlying stream.
336    fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
337    where
338        R: BitRead + ?Sized,
339        Self: Sized;
340
341    /// Writes ourself to the stream using a variable width integer.
342    ///
343    /// # Errors
344    ///
345    /// Passes along any I/O error from the underlying stream.
346    fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
347        self,
348        writer: &mut W,
349    ) -> io::Result<()>;
350}
351
352/// Reading and writing booleans as `Integer` requires the number of bits to be 1.
353///
354/// This is more useful when combined with the fixed array target
355/// for reading blocks of bit flags.
356///
357/// # Example
358/// ```
359/// use bitstream_io::{BitReader, BitRead, BigEndian};
360///
361/// #[derive(Debug, PartialEq, Eq)]
362/// struct Flags {
363///     a: bool,
364///     b: bool,
365///     c: bool,
366///     d: bool,
367/// }
368///
369/// let data: &[u8] = &[0b1011_0000];
370/// let mut r = BitReader::endian(data, BigEndian);
371/// // note the number of bits must be 1 per read
372/// // while the quantity of flags is indicated by the array length
373/// let flags = r.read::<1, [bool; 4]>().map(|[a, b, c, d]| Flags { a, b, c, d }).unwrap();
374/// assert_eq!(flags, Flags { a: true, b: false, c: true, d: true });
375/// ```
376impl Integer for bool {
377    #[inline(always)]
378    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
379    where
380        Self: Sized,
381    {
382        const {
383            assert!(BITS == 1, "booleans require exactly 1 bit");
384        }
385
386        reader.read_bit()
387    }
388
389    fn read_var<const MAX: u32, R>(
390        reader: &mut R,
391        BitCount { bits }: BitCount<MAX>,
392    ) -> io::Result<Self>
393    where
394        R: BitRead + ?Sized,
395        Self: Sized,
396    {
397        if bits == 1 {
398            reader.read_bit()
399        } else {
400            Err(io::Error::new(
401                io::ErrorKind::InvalidInput,
402                "booleans require exactly 1 bit",
403            ))
404        }
405    }
406
407    #[inline(always)]
408    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
409        const {
410            assert!(BITS == 1, "booleans require exactly 1 bit");
411        }
412
413        writer.write_bit(self)
414    }
415
416    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
417        self,
418        writer: &mut W,
419        BitCount { bits }: BitCount<MAX>,
420    ) -> io::Result<()> {
421        if bits == 1 {
422            writer.write_bit(self)
423        } else {
424            Err(io::Error::new(
425                io::ErrorKind::InvalidInput,
426                "booleans require exactly 1 bit",
427            ))
428        }
429    }
430}
431
432impl<const SIZE: usize, I: Integer + Copy + Default> Integer for [I; SIZE] {
433    #[inline]
434    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
435    where
436        Self: Sized,
437    {
438        let mut a = [I::default(); SIZE];
439
440        a.iter_mut().try_for_each(|v| {
441            *v = reader.read::<BITS, I>()?;
442            Ok::<(), io::Error>(())
443        })?;
444
445        Ok(a)
446    }
447
448    #[inline]
449    fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
450    where
451        R: BitRead + ?Sized,
452        Self: Sized,
453    {
454        let mut a = [I::default(); SIZE];
455
456        a.iter_mut().try_for_each(|v| {
457            *v = reader.read_counted(count)?;
458            Ok::<(), io::Error>(())
459        })?;
460
461        Ok(a)
462    }
463
464    #[inline]
465    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
466        IntoIterator::into_iter(self).try_for_each(|v| writer.write::<BITS, I>(v))
467    }
468
469    #[inline]
470    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
471        self,
472        writer: &mut W,
473        count: BitCount<MAX>,
474    ) -> io::Result<()> {
475        IntoIterator::into_iter(self).try_for_each(|v| writer.write_counted(count, v))
476    }
477}
478
479impl<const SIZE: usize, I: VBRInteger + Copy + Default> VBRInteger for [I; SIZE] {
480    fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
481    where
482        R: BitRead + ?Sized,
483        Self: Sized,
484    {
485        let mut a = [I::default(); SIZE];
486
487        a.iter_mut().try_for_each(|v| {
488            I::read_vbr::<FIELD_SIZE, R>(reader).map(|item| {
489                *v = item;
490            })
491        })?;
492
493        Ok(a)
494    }
495
496    fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
497        self,
498        writer: &mut W,
499    ) -> io::Result<()> {
500        IntoIterator::into_iter(self).try_for_each(|v| I::write_vbr::<FIELD_SIZE, W>(v, writer))
501    }
502}
503
504/// This trait extends many common integer types (both unsigned and signed)
505/// with a few trivial methods so that they can be used
506/// with the bitstream handling traits.
507pub trait Numeric:
508    Primitive
509    + Sized
510    + Copy
511    + Default
512    + Debug
513    + PartialOrd
514    + Shl<u32, Output = Self>
515    + ShlAssign<u32>
516    + Shr<u32, Output = Self>
517    + ShrAssign<u32>
518    + Rem<Self, Output = Self>
519    + RemAssign<Self>
520    + BitAnd<Self, Output = Self>
521    + BitOr<Self, Output = Self>
522    + BitOrAssign<Self>
523    + BitXor<Self, Output = Self>
524    + Not<Output = Self>
525    + Sub<Self, Output = Self>
526{
527    /// Size of type in bits
528    const BITS_SIZE: u32;
529
530    /// The value of 0 in this type
531    const ZERO: Self;
532
533    /// The value of 1 in this type
534    const ONE: Self;
535
536    /// Returns a `u8` value in this type
537    fn from_u8(u: u8) -> Self;
538
539    /// Assuming 0 <= value < 256, returns this value as a `u8` type
540    fn to_u8(self) -> u8;
541}
542
543macro_rules! define_numeric {
544    ($t:ty) => {
545        define_primitive_numeric!($t);
546
547        impl Numeric for $t {
548            const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
549
550            const ZERO: Self = 0;
551
552            const ONE: Self = 1;
553
554            #[inline(always)]
555            fn from_u8(u: u8) -> Self {
556                u as $t
557            }
558            #[inline(always)]
559            fn to_u8(self) -> u8 {
560                self as u8
561            }
562        }
563    };
564}
565
566/// This trait extends many common unsigned integer types
567/// so that they can be used with the bitstream handling traits.
568pub trait UnsignedInteger: Numeric {
569    /// This type's most-significant bit
570    const MSB_BIT: Self;
571
572    /// This type's least significant bit
573    const LSB_BIT: Self;
574
575    /// This type with all bits set
576    const ALL: Self;
577
578    /// The signed variant of ourself
579    type Signed: SignedInteger<Unsigned = Self>;
580
581    /// Given a twos-complement value,
582    /// return this value is a non-negative signed number.
583    /// The location of the sign bit depends on the stream's endianness
584    /// and is not stored in the result.
585    ///
586    /// # Example
587    /// ```
588    /// use bitstream_io::UnsignedInteger;
589    /// assert_eq!(0b00000001u8.as_non_negative(), 1i8);
590    /// ```
591    fn as_non_negative(self) -> Self::Signed;
592
593    /// Given a two-complement positive value and certain number of bits,
594    /// returns this value as a negative signed number.
595    /// The location of the sign bit depends on the stream's endianness
596    /// and is not stored in the result.
597    ///
598    /// # Example
599    /// ```
600    /// use bitstream_io::UnsignedInteger;
601    /// assert_eq!(0b01111111u8.as_negative(8), -1i8);
602    /// ```
603    fn as_negative(self, bits: u32) -> Self::Signed;
604
605    /// Given a two-complement positive value and certain number of bits,
606    /// returns this value as a negative number.
607    ///
608    /// # Example
609    /// ```
610    /// use bitstream_io::UnsignedInteger;
611    /// assert_eq!(0b01111111u8.as_negative_fixed::<8>(), -1i8);
612    /// ```
613    fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed;
614
615    /// Checked shift left
616    fn checked_shl(self, rhs: u32) -> Option<Self>;
617
618    /// Checked shift right
619    fn checked_shr(self, rhs: u32) -> Option<Self>;
620
621    /// Shift left up to our length in bits
622    ///
623    /// If rhs equals our length in bits, returns default
624    fn shl_default(self, rhs: u32) -> Self {
625        self.checked_shl(rhs).unwrap_or(Self::ZERO)
626    }
627
628    /// Shift left up to our length in bits
629    ///
630    /// If rhs equals our length in bits, returns zero
631    fn shr_default(self, rhs: u32) -> Self {
632        self.checked_shr(rhs).unwrap_or(Self::ZERO)
633    }
634}
635
636macro_rules! define_unsigned_integer {
637    ($t:ty, $s:ty) => {
638        define_numeric!($t);
639
640        impl UnsignedInteger for $t {
641            type Signed = $s;
642
643            const MSB_BIT: Self = 1 << (Self::BITS_SIZE - 1);
644
645            const LSB_BIT: Self = 1;
646
647            const ALL: Self = <$t>::MAX;
648
649            #[inline(always)]
650            fn as_non_negative(self) -> Self::Signed {
651                self as $s
652            }
653            #[inline(always)]
654            fn as_negative(self, bits: u32) -> Self::Signed {
655                (self as $s) + (-1 << (bits - 1))
656            }
657            #[inline(always)]
658            fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed {
659                (self as $s) + (-1 << (BITS - 1))
660            }
661            #[inline(always)]
662            fn checked_shl(self, rhs: u32) -> Option<Self> {
663                self.checked_shl(rhs)
664            }
665            #[inline(always)]
666            fn checked_shr(self, rhs: u32) -> Option<Self> {
667                self.checked_shr(rhs)
668            }
669            // TODO - enable these in the future
670            // #[inline(always)]
671            // fn shl_default(self, rhs: u32) -> Self {
672            //     self.unbounded_shl(rhs)
673            // }
674            // #[inline(always)]
675            // fn shr_default(self, rhs: u32) -> Self {
676            //     self.unbounded_shr(rhs)
677            // }
678        }
679
680        impl Integer for $t {
681            #[inline(always)]
682            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
683            where
684                Self: Sized,
685            {
686                reader.read_unsigned::<BITS, _>()
687            }
688
689            #[inline(always)]
690            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
691            where
692                R: BitRead + ?Sized,
693                Self: Sized,
694            {
695                reader.read_unsigned_counted::<MAX, _>(bits)
696            }
697
698            #[inline(always)]
699            fn write<const BITS: u32, W: BitWrite + ?Sized>(
700                self,
701                writer: &mut W,
702            ) -> io::Result<()> {
703                writer.write_unsigned::<BITS, _>(self)
704            }
705
706            #[inline(always)]
707            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
708                self,
709                writer: &mut W,
710                bits: BitCount<MAX>,
711            ) -> io::Result<()> {
712                writer.write_unsigned_counted(bits, self)
713            }
714        }
715
716        impl VBRInteger for $t {
717            #[inline(always)]
718            fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
719            where
720                R: BitRead + ?Sized,
721                Self: Sized,
722            {
723                reader.read_unsigned_vbr::<FIELD_SIZE, _>()
724            }
725
726            #[inline(always)]
727            fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
728                self,
729                writer: &mut W,
730            ) -> io::Result<()> {
731                writer.write_unsigned_vbr::<FIELD_SIZE, _>(self)
732            }
733        }
734
735        /// Unsigned NonZero types increment their value by 1
736        /// when being read and decrement it by 1
737        /// when being written.
738        ///
739        /// # Examples
740        /// ```
741        /// use bitstream_io::{BitReader, BitRead, BigEndian};
742        /// use core::num::NonZero;
743        ///
744        /// let data: &[u8] = &[0b001_00000];
745        /// // reading a regular u8 in 3 bits yields 1
746        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, u8>().unwrap(), 1);
747        /// // reading a NonZero<u8> in 3 bits of the same data yields 2
748        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, NonZero<u8>>().unwrap().get(), 2);
749        /// ```
750        ///
751        /// ```
752        /// use bitstream_io::{BitWriter, BitWrite, BigEndian};
753        /// use core::num::NonZero;
754        ///
755        /// let mut w = BitWriter::endian(vec![], BigEndian);
756        /// // writing 1 as a regular u8 in 3 bits
757        /// w.write::<3, u8>(1).unwrap();
758        /// w.byte_align();
759        /// assert_eq!(w.into_writer(), &[0b001_00000]);
760        ///
761        /// let mut w = BitWriter::endian(vec![], BigEndian);
762        /// // writing 1 as a NonZero<u8> in 3 bits
763        /// w.write::<3, NonZero<u8>>(NonZero::new(1).unwrap()).unwrap();
764        /// w.byte_align();
765        /// assert_eq!(w.into_writer(), &[0b000_00000]);
766        /// ```
767        impl Integer for NonZero<$t> {
768            #[inline]
769            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
770            where
771                Self: Sized,
772            {
773                const {
774                    assert!(
775                        BITS < <$t>::BITS_SIZE,
776                        "BITS must be less than the type's size in bits"
777                    );
778                }
779
780                <$t as Integer>::read::<BITS, R>(reader).map(|u| NonZero::new(u + 1).unwrap())
781            }
782
783            #[inline]
784            fn read_var<const MAX: u32, R>(
785                reader: &mut R,
786                count @ BitCount { bits }: BitCount<MAX>,
787            ) -> io::Result<Self>
788            where
789                R: BitRead + ?Sized,
790                Self: Sized,
791            {
792                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
793                    <$t as Integer>::read_var::<MAX, R>(reader, count)
794                        .map(|u| NonZero::new(u + 1).unwrap())
795                } else {
796                    Err(io::Error::new(
797                        io::ErrorKind::InvalidInput,
798                        "bit count must be less than the type's size in bits",
799                    ))
800                }
801            }
802
803            #[inline]
804            fn write<const BITS: u32, W: BitWrite + ?Sized>(
805                self,
806                writer: &mut W,
807            ) -> io::Result<()> {
808                const {
809                    assert!(
810                        BITS < <$t>::BITS_SIZE,
811                        "BITS must be less than the type's size in bits"
812                    );
813                }
814
815                <$t as Integer>::write::<BITS, W>(self.get() - 1, writer)
816            }
817
818            #[inline]
819            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
820                self,
821                writer: &mut W,
822                count @ BitCount { bits }: BitCount<MAX>,
823            ) -> io::Result<()> {
824                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
825                    <$t as Integer>::write_var::<MAX, W>(self.get() - 1, writer, count)
826                } else {
827                    Err(io::Error::new(
828                        io::ErrorKind::InvalidInput,
829                        "bit count must be less than the type's size in bits",
830                    ))
831                }
832            }
833        }
834
835        impl VBRInteger for NonZero<$t> {
836            #[inline]
837            fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
838            where
839                R: BitRead + ?Sized,
840                Self: Sized,
841            {
842                <$t as VBRInteger>::read_vbr::<FIELD_SIZE, R>(reader)
843                    .map(|u| NonZero::new(u + 1).unwrap())
844            }
845
846            #[inline]
847            fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
848                self,
849                writer: &mut W,
850            ) -> io::Result<()> {
851                <$t as VBRInteger>::write_vbr::<FIELD_SIZE, W>(self.get() - 1, writer)
852            }
853        }
854
855        impl Integer for Option<NonZero<$t>> {
856            #[inline]
857            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
858            where
859                Self: Sized,
860            {
861                <$t as Integer>::read::<BITS, R>(reader).map(NonZero::new)
862            }
863
864            #[inline]
865            fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
866            where
867                R: BitRead + ?Sized,
868                Self: Sized,
869            {
870                <$t as Integer>::read_var::<MAX, R>(reader, count).map(NonZero::new)
871            }
872
873            #[inline]
874            fn write<const BITS: u32, W: BitWrite + ?Sized>(
875                self,
876                writer: &mut W,
877            ) -> io::Result<()> {
878                <$t as Integer>::write::<BITS, W>(self.map(|n| n.get()).unwrap_or(0), writer)
879            }
880
881            #[inline]
882            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
883                self,
884                writer: &mut W,
885                count: BitCount<MAX>,
886            ) -> io::Result<()> {
887                <$t as Integer>::write_var::<MAX, W>(
888                    self.map(|n| n.get()).unwrap_or(0),
889                    writer,
890                    count,
891                )
892            }
893        }
894
895        impl VBRInteger for Option<NonZero<$t>> {
896            #[inline(always)]
897            fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
898            where
899                R: BitRead + ?Sized,
900                Self: Sized,
901            {
902                <$t as VBRInteger>::read_vbr::<FIELD_SIZE, _>(reader).map(NonZero::new)
903            }
904
905            #[inline]
906            fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
907                self,
908                writer: &mut W,
909            ) -> io::Result<()> {
910                <$t as VBRInteger>::write_vbr::<FIELD_SIZE, W>(
911                    self.map(|n| n.get()).unwrap_or(0),
912                    writer,
913                )
914            }
915        }
916    };
917}
918
919/// This trait extends many common signed integer types
920/// so that they can be used with the bitstream handling traits.
921///
922/// This trait was formerly named `SignedNumeric` in 2.X.X code.
923/// If backwards-compatibility is needed one can
924/// import `SignedInteger` as `SignedNumeric`.
925pub trait SignedInteger: Numeric {
926    /// The unsigned variant of ourself
927    type Unsigned: UnsignedInteger<Signed = Self>;
928
929    /// Returns true if this value is negative
930    ///
931    /// # Example
932    /// ```
933    /// use bitstream_io::SignedInteger;
934    /// assert!(!1i8.is_negative());
935    /// assert!((-1i8).is_negative());
936    /// ```
937    fn is_negative(self) -> bool;
938
939    /// Returns ourself as a non-negative value.
940    /// The location of the sign bit depends on the stream's endianness
941    /// and is not stored in the result.
942    ///
943    /// # Example
944    /// ```
945    /// use bitstream_io::SignedInteger;
946    /// assert_eq!(1i8.as_non_negative(), 0b00000001u8);
947    /// ```
948    fn as_non_negative(self) -> Self::Unsigned;
949
950    /// Given a negative value and a certain number of bits,
951    /// returns this value as a twos-complement positive number.
952    /// The location of the sign bit depends on the stream's endianness
953    /// and is not stored in the result.
954    ///
955    /// # Example
956    /// ```
957    /// use bitstream_io::SignedInteger;
958    /// assert_eq!((-1i8).as_negative(8), 0b01111111u8);
959    /// ```
960    fn as_negative(self, bits: u32) -> Self::Unsigned;
961
962    /// Given a negative value and a certain number of bits,
963    /// returns this value as a twos-complement positive number.
964    ///
965    /// # Example
966    /// ```
967    /// use bitstream_io::SignedInteger;
968    /// assert_eq!((-1i8).as_negative_fixed::<8>(), 0b01111111u8);
969    /// ```
970    fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned;
971}
972
973macro_rules! define_signed_integer {
974    ($t:ty, $u:ty) => {
975        define_numeric!($t);
976
977        impl SignedInteger for $t {
978            type Unsigned = $u;
979
980            #[inline(always)]
981            fn is_negative(self) -> bool {
982                self.is_negative()
983            }
984            fn as_non_negative(self) -> Self::Unsigned {
985                self as $u
986            }
987            fn as_negative(self, bits: u32) -> Self::Unsigned {
988                (self - (-1 << (bits - 1))) as $u
989            }
990            fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned {
991                (self - (-1 << (BITS - 1))) as $u
992            }
993        }
994
995        impl Integer for $t {
996            #[inline(always)]
997            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
998            where
999                Self: Sized,
1000            {
1001                reader.read_signed::<BITS, _>()
1002            }
1003
1004            #[inline(always)]
1005            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
1006            where
1007                R: BitRead + ?Sized,
1008                Self: Sized,
1009            {
1010                reader.read_signed_counted::<MAX, _>(bits)
1011            }
1012
1013            #[inline(always)]
1014            fn write<const BITS: u32, W: BitWrite + ?Sized>(
1015                self,
1016                writer: &mut W,
1017            ) -> io::Result<()> {
1018                writer.write_signed::<BITS, _>(self)
1019            }
1020
1021            #[inline(always)]
1022            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
1023                self,
1024                writer: &mut W,
1025                bits: BitCount<MAX>,
1026            ) -> io::Result<()> {
1027                writer.write_signed_counted::<MAX, _>(bits, self)
1028            }
1029        }
1030
1031        impl VBRInteger for $t {
1032            #[inline(always)]
1033            fn read_vbr<const FIELD_SIZE: u32, R>(reader: &mut R) -> io::Result<Self>
1034            where
1035                R: BitRead + ?Sized,
1036                Self: Sized,
1037            {
1038                reader.read_signed_vbr::<FIELD_SIZE, _>()
1039            }
1040
1041            #[inline(always)]
1042            fn write_vbr<const FIELD_SIZE: u32, W: BitWrite + ?Sized>(
1043                self,
1044                writer: &mut W,
1045            ) -> io::Result<()> {
1046                writer.write_signed_vbr::<FIELD_SIZE, _>(self)
1047            }
1048        }
1049    };
1050}
1051
1052define_unsigned_integer!(u8, i8);
1053define_unsigned_integer!(u16, i16);
1054define_unsigned_integer!(u32, i32);
1055define_unsigned_integer!(u64, i64);
1056define_unsigned_integer!(u128, i128);
1057
1058define_signed_integer!(i8, u8);
1059define_signed_integer!(i16, u16);
1060define_signed_integer!(i32, u32);
1061define_signed_integer!(i64, u64);
1062define_signed_integer!(i128, u128);
1063
1064define_primitive_numeric!(f32);
1065define_primitive_numeric!(f64);
1066
1067mod private {
1068    use crate::{
1069        io, BitCount, BitRead, BitWrite, CheckedSigned, CheckedUnsigned, Primitive, SignedBitCount,
1070        SignedInteger, UnsignedInteger,
1071    };
1072
1073    #[test]
1074    fn test_checked_signed() {
1075        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<8>(), -128i8).is_ok());
1076        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<8>(), 127i8).is_ok());
1077        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), -64i8).is_ok());
1078        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), 63i8).is_ok());
1079        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), -32i8).is_ok());
1080        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), 31i8).is_ok());
1081        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), -16i8).is_ok());
1082        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), 15i8).is_ok());
1083        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), -8i8).is_ok());
1084        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), 7i8).is_ok());
1085        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), -4i8).is_ok());
1086        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), 3i8).is_ok());
1087        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), -2i8).is_ok());
1088        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), 1i8).is_ok());
1089        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), -1i8).is_ok());
1090        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), 0i8).is_ok());
1091
1092        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), -65i8).is_err());
1093        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), 64i8).is_err());
1094        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), -33i8).is_err());
1095        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), 32i8).is_err());
1096        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), -17i8).is_err());
1097        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), 16i8).is_err());
1098        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), -9i8).is_err());
1099        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), 8i8).is_err());
1100        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), -5i8).is_err());
1101        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), 4i8).is_err());
1102        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), -3i8).is_err());
1103        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), 2i8).is_err());
1104        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), -2i8).is_err());
1105        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), 1i8).is_err());
1106    }
1107
1108    pub trait Endianness: Sized {
1109        /// Pops the next bit from the queue,
1110        /// repleneshing it from the given reader if necessary
1111        fn pop_bit_refill<R>(
1112            reader: &mut R,
1113            queue_value: &mut u8,
1114            queue_bits: &mut u32,
1115        ) -> io::Result<bool>
1116        where
1117            R: io::Read;
1118
1119        /// Pops the next unary value from the source until
1120        /// `STOP_BIT` is encountered, replenishing it from the given
1121        /// closure if necessary.
1122        ///
1123        /// `STOP_BIT` must be 0 or 1.
1124        fn pop_unary<const STOP_BIT: u8, R>(
1125            reader: &mut R,
1126            queue_value: &mut u8,
1127            queue_bits: &mut u32,
1128        ) -> io::Result<u32>
1129        where
1130            R: io::Read;
1131
1132        /// Pushes the next bit into the queue,
1133        /// and returns `Some` value if the queue is full.
1134        fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8>;
1135
1136        /// For performing bulk reads from a bit source to an output type.
1137        fn read_bits<const MAX: u32, R, U>(
1138            reader: &mut R,
1139            queue_value: &mut u8,
1140            queue_bits: &mut u32,
1141            count: BitCount<MAX>,
1142        ) -> io::Result<U>
1143        where
1144            R: io::Read,
1145            U: UnsignedInteger;
1146
1147        /// For performing bulk reads from a bit source to an output type.
1148        fn read_bits_fixed<const BITS: u32, R, U>(
1149            reader: &mut R,
1150            queue_value: &mut u8,
1151            queue_bits: &mut u32,
1152        ) -> io::Result<U>
1153        where
1154            R: io::Read,
1155            U: UnsignedInteger;
1156
1157        /// For performing a checked write to a bit sink
1158        fn write_bits_checked<const MAX: u32, W, U>(
1159            writer: &mut W,
1160            queue_value: &mut u8,
1161            queue_bits: &mut u32,
1162            value: CheckedUnsigned<MAX, U>,
1163        ) -> io::Result<()>
1164        where
1165            W: io::Write,
1166            U: UnsignedInteger;
1167
1168        /// For performing a checked signed write to a bit sink
1169        fn write_signed_bits_checked<const MAX: u32, W, S>(
1170            writer: &mut W,
1171            queue_value: &mut u8,
1172            queue_bits: &mut u32,
1173            value: CheckedSigned<MAX, S>,
1174        ) -> io::Result<()>
1175        where
1176            W: io::Write,
1177            S: SignedInteger;
1178
1179        /// Reads signed value from reader in this endianness
1180        fn read_signed_counted<const MAX: u32, R, S>(
1181            r: &mut R,
1182            bits: SignedBitCount<MAX>,
1183        ) -> io::Result<S>
1184        where
1185            R: BitRead,
1186            S: SignedInteger;
1187
1188        /// Reads whole set of bytes to output buffer
1189        fn read_bytes<const CHUNK_SIZE: usize, R>(
1190            reader: &mut R,
1191            queue_value: &mut u8,
1192            queue_bits: u32,
1193            buf: &mut [u8],
1194        ) -> io::Result<()>
1195        where
1196            R: io::Read;
1197
1198        /// Writes whole set of bytes to output buffer
1199        fn write_bytes<const CHUNK_SIZE: usize, W>(
1200            writer: &mut W,
1201            queue_value: &mut u8,
1202            queue_bits: u32,
1203            buf: &[u8],
1204        ) -> io::Result<()>
1205        where
1206            W: io::Write;
1207
1208        /// Converts a primitive's byte buffer to a primitive
1209        fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P;
1210
1211        /// Converts a primitive to a primitive's byte buffer
1212        fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes;
1213
1214        /// Reads convertable numeric value from reader in this endianness
1215        #[deprecated(since = "4.0.0")]
1216        fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
1217        where
1218            R: BitRead,
1219            V: Primitive;
1220
1221        /// Writes convertable numeric value to writer in this endianness
1222        #[deprecated(since = "4.0.0")]
1223        fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
1224        where
1225            W: BitWrite,
1226            V: Primitive;
1227    }
1228
1229    pub trait Checkable {
1230        fn write_endian<E, W>(
1231            self,
1232            writer: &mut W,
1233            queue_value: &mut u8,
1234            queue_bits: &mut u32,
1235        ) -> io::Result<()>
1236        where
1237            E: Endianness,
1238            W: io::Write;
1239    }
1240}
1241
1242/// A stream's endianness, or byte order, for determining
1243/// how bits should be read.
1244///
1245/// It comes in `BigEndian` and `LittleEndian` varieties
1246/// (which may be shortened to `BE` and `LE`)
1247/// and is not something programmers should implement directly.
1248pub trait Endianness: private::Endianness {}
1249
1250#[inline(always)]
1251fn read_byte<R>(mut reader: R) -> io::Result<u8>
1252where
1253    R: io::Read,
1254{
1255    let mut byte = 0;
1256    reader
1257        .read_exact(core::slice::from_mut(&mut byte))
1258        .map(|()| byte)
1259}
1260
1261#[inline(always)]
1262fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1263where
1264    W: io::Write,
1265{
1266    writer.write_all(core::slice::from_ref(&byte))
1267}
1268
1269/// A number of bits to be consumed or written, with a known maximum
1270///
1271/// Although [`BitRead::read`] and [`BitWrite::write`] should be
1272/// preferred when the number of bits is fixed and known at compile-time -
1273/// because they can validate the bit count is less than or equal
1274/// to the type's size in bits at compile-time -
1275/// there are many instances where bit count is dynamic and
1276/// determined by the file format itself.
1277/// But when using [`BitRead::read_var`] or [`BitWrite::write_var`]
1278/// we must pessimistically assume any number of bits as an argument
1279/// and validate that the number of bits is not larger than the
1280/// type being read or written on every call.
1281///
1282/// ```
1283/// use bitstream_io::{BitRead, BitReader, BigEndian};
1284///
1285/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1286/// let mut r = BitReader::endian(data, BigEndian);
1287/// // our bit count is a 3 bit value
1288/// let count = r.read::<3, u32>().unwrap();
1289/// // that count indicates we need to read 4 bits (0b100)
1290/// assert_eq!(count, 4);
1291/// // read the first 4-bit value
1292/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0001);
1293/// // read the second 4-bit value
1294/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b1111);
1295/// // read the third 4-bit value
1296/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0110);
1297/// ```
1298///
1299/// In the preceding example, even though we know `count` is a
1300/// 3 bit value whose maximum value will never be greater than 7,
1301/// the subsequent `read_var` calls have no way to know that.
1302/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1303/// and validate the count is not larger than the `u8` types we're reading.
1304///
1305/// But we can convert our example to use the `BitCount` type:
1306///
1307/// ```
1308/// use bitstream_io::{BitRead, BitReader, BigEndian, BitCount};
1309///
1310/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1311/// let mut r = BitReader::endian(data, BigEndian);
1312/// // our bit count is a 3 bit value with a maximum value of 7
1313/// let count = r.read_count::<0b111>().unwrap();
1314/// // that count indicates we need to read 4 bits (0b100)
1315/// assert_eq!(count, BitCount::<7>::new::<4>());
1316/// // read the first 4-bit value
1317/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0001);
1318/// // read the second 4-bit value
1319/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b1111);
1320/// // read the third 4-bit value
1321/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0110);
1322/// ```
1323///
1324/// Because the [`BitRead::read_counted`] methods know at compile-time
1325/// that the bit count will be larger than 7, that check can be eliminated
1326/// simply by taking advantage of information we already know.
1327///
1328/// Leveraging the `BitCount` type also allows us to reason about
1329/// bit counts in a more formal way, and use checked permutation methods
1330/// to modify them while ensuring they remain constrained by
1331/// the file format's requirements.
1332#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1333pub struct BitCount<const MAX: u32> {
1334    // The amount of bits may be less than or equal to the maximum,
1335    // but never more.
1336    bits: u32,
1337}
1338
1339impl<const MAX: u32> BitCount<MAX> {
1340    /// Builds a bit count from a constant number
1341    /// of bits, which must not be greater than `MAX`.
1342    ///
1343    /// Intended to be used for defining constants.
1344    ///
1345    /// Use `TryFrom` to conditionally build
1346    /// counts from values at runtime.
1347    ///
1348    /// # Examples
1349    ///
1350    /// ```
1351    /// use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
1352    /// let data: &[u8] = &[0b111_00000];
1353    /// let mut r = BitReader::endian(data, BigEndian);
1354    /// // reading 3 bits from a stream out of a maximum of 8
1355    /// // doesn't require checking that the bit count is larger
1356    /// // than a u8 at runtime because specifying the maximum of 8
1357    /// // guarantees our bit count will not be larger than 8
1358    /// assert_eq!(r.read_counted::<8, u8>(BitCount::new::<3>()).unwrap(), 0b111);
1359    /// ```
1360    ///
1361    /// ```rust,compile_fail
1362    /// use bitstream_io::BitCount;
1363    /// // trying to build a count of 10 with a maximum of 8
1364    /// // fails to compile at all
1365    /// let count = BitCount::<8>::new::<10>();
1366    /// ```
1367    pub const fn new<const BITS: u32>() -> Self {
1368        const {
1369            assert!(BITS <= MAX, "BITS must be <= MAX");
1370        }
1371
1372        Self { bits: BITS }
1373    }
1374
1375    /// Add a number of bits to our count,
1376    /// returning a new count with a new maximum.
1377    ///
1378    /// Returns `None` if the new count goes above our new maximum.
1379    ///
1380    /// # Examples
1381    ///
1382    /// ```
1383    /// use bitstream_io::BitCount;
1384    ///
1385    /// let count = BitCount::<2>::new::<1>();
1386    /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1387    /// assert_eq!(count.checked_add::<3>(2), Some(BitCount::<3>::new::<3>()));
1388    /// // adding 2 to 1 without increasing the max yields None
1389    /// assert_eq!(count.checked_add::<2>(2), None);
1390    /// ```
1391    #[inline]
1392    pub const fn checked_add<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1393        match self.bits.checked_add(bits) {
1394            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1395            _ => None,
1396        }
1397    }
1398
1399    /// Subtracts a number of bits from our count,
1400    /// returning a new count with a new maximum.
1401    ///
1402    /// Returns `None` if the new count goes below 0
1403    /// or below our new maximum.
1404    ///
1405    /// # Example
1406    /// ```
1407    /// use bitstream_io::BitCount;
1408    /// let count = BitCount::<5>::new::<5>();
1409    /// // subtracting 1 from 5 yields a new count of 4
1410    /// assert_eq!(count.checked_sub::<5>(1), Some(BitCount::<5>::new::<4>()));
1411    /// // subtracting 6 from 5 yields None
1412    /// assert!(count.checked_sub::<5>(6).is_none());
1413    /// // subtracting 1 with a new maximum of 3 also yields None
1414    /// // because 4 is larger than the maximum of 3
1415    /// assert!(count.checked_sub::<3>(1).is_none());
1416    /// ```
1417    #[inline]
1418    pub const fn checked_sub<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1419        match self.bits.checked_sub(bits) {
1420            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1421            _ => None,
1422        }
1423    }
1424
1425    /// Attempt to convert our count to a count with a new
1426    /// bit count and new maximum.
1427    ///
1428    /// Returns `Some(count)` if the updated number of bits
1429    /// is less than or equal to the new maximum.
1430    /// Returns `None` if not.
1431    ///
1432    /// # Examples
1433    /// ```
1434    /// use bitstream_io::BitCount;
1435    ///
1436    /// let count = BitCount::<5>::new::<5>();
1437    /// // muliplying 5 bits by 2 with a new max of 10 is ok
1438    /// assert_eq!(
1439    ///     count.try_map::<10, _>(|i| i.checked_mul(2)),
1440    ///     Some(BitCount::<10>::new::<10>()),
1441    /// );
1442    ///
1443    /// // multiplying 5 bits by 3 with a new max of 10 overflows
1444    /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1445    /// ```
1446    #[inline]
1447    pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<BitCount<NEW_MAX>>
1448    where
1449        F: FnOnce(u32) -> Option<u32>,
1450    {
1451        f(self.bits)
1452            .filter(|bits| *bits <= NEW_MAX)
1453            .map(|bits| BitCount { bits })
1454    }
1455
1456    /// Returns our maximum bit count
1457    ///
1458    /// # Example
1459    /// ```
1460    /// use bitstream_io::BitCount;
1461    ///
1462    /// let count = BitCount::<10>::new::<5>();
1463    /// assert_eq!(count.max(), 10);
1464    /// ```
1465    #[inline(always)]
1466    pub const fn max(&self) -> u32 {
1467        MAX
1468    }
1469
1470    /// Returns signed count if our bit count is greater than 0
1471    ///
1472    /// # Example
1473    ///
1474    /// ```
1475    /// use bitstream_io::{BitCount, SignedBitCount};
1476    ///
1477    /// let count = BitCount::<10>::new::<5>();
1478    /// assert_eq!(count.signed_count(), Some(SignedBitCount::<10>::new::<5>()));
1479    ///
1480    /// let count = BitCount::<10>::new::<0>();
1481    /// assert_eq!(count.signed_count(), None);
1482    /// ```
1483    #[inline(always)]
1484    pub const fn signed_count(&self) -> Option<SignedBitCount<MAX>> {
1485        match self.bits.checked_sub(1) {
1486            Some(bits) => Some(SignedBitCount {
1487                bits: *self,
1488                unsigned: BitCount { bits },
1489            }),
1490            None => None,
1491        }
1492    }
1493
1494    /// Masks off the least-significant bits for the given type
1495    ///
1496    /// Returns closure that takes a value and returns a
1497    /// pair of the most-significant and least-significant
1498    /// bits.  Because the least-significant bits cannot
1499    /// be larger than this bit count, that value is
1500    /// returned as a [`Checked`] type.
1501    ///
1502    /// # Examples
1503    ///
1504    /// ```
1505    /// use bitstream_io::BitCount;
1506    ///
1507    /// // create a bit count of 3
1508    /// let count = BitCount::<8>::new::<3>();
1509    ///
1510    /// // create a mask suitable for u8 types
1511    /// let mask = count.mask_lsb::<u8>();
1512    ///
1513    /// let (msb, lsb) = mask(0b11011_110);
1514    /// assert_eq!(msb, 0b11011);             // the most-significant bits
1515    /// assert_eq!(lsb.into_value(), 0b110);  // the least-significant bits
1516    ///
1517    /// let (msb, lsb) = mask(0b01100_010);
1518    /// assert_eq!(msb, 0b01100);             // the most-significant bits
1519    /// assert_eq!(lsb.into_value(), 0b010);  // the least-significant bits
1520    ///
1521    /// let (msb, lsb) = mask(0b00000_111);
1522    /// assert_eq!(msb, 0b00000);             // the most-significant bits
1523    /// assert_eq!(lsb.into_value(), 0b111);  // the least-significant bits
1524    /// ```
1525    ///
1526    /// ```
1527    /// use bitstream_io::BitCount;
1528    ///
1529    /// // a mask with a bit count of 0 puts everything in msb
1530    /// let mask = BitCount::<8>::new::<0>().mask_lsb::<u8>();
1531    ///
1532    /// let (msb, lsb) = mask(0b11111111);
1533    /// assert_eq!(msb, 0b11111111);
1534    /// assert_eq!(lsb.into_value(), 0);
1535    ///
1536    /// // a mask with a bit count larger than the type
1537    /// // is restricted to that type's size, if possible
1538    /// let mask = BitCount::<16>::new::<9>().mask_lsb::<u8>();
1539    ///
1540    /// let (msb, lsb) = mask(0b11111111);
1541    /// assert_eq!(msb, 0);
1542    /// assert_eq!(lsb.into_value(), 0b11111111);
1543    /// ```
1544    pub fn mask_lsb<U: UnsignedInteger>(self) -> impl Fn(U) -> (U, CheckedUnsigned<MAX, U>) {
1545        use core::convert::TryFrom;
1546
1547        let (mask, shift, count) = match U::BITS_SIZE.checked_sub(self.bits) {
1548            Some(mask_bits) => (U::ALL.shr_default(mask_bits), self.bits, self),
1549            None => (
1550                U::ALL,
1551                U::BITS_SIZE,
1552                BitCount::try_from(U::BITS_SIZE).expect("bit count too small for type"),
1553            ),
1554        };
1555
1556        move |v| {
1557            (
1558                v.shr_default(shift),
1559                Checked {
1560                    value: v & mask,
1561                    count,
1562                },
1563            )
1564        }
1565    }
1566
1567    /// Returns this bit count's range for the given unsigned type
1568    ///
1569    /// # Example
1570    ///
1571    /// ```
1572    /// use bitstream_io::BitCount;
1573    ///
1574    /// assert_eq!(BitCount::<9>::new::<0>().range::<u8>(), 0..=0);
1575    /// assert_eq!(BitCount::<9>::new::<1>().range::<u8>(), 0..=0b1);
1576    /// assert_eq!(BitCount::<9>::new::<2>().range::<u8>(), 0..=0b11);
1577    /// assert_eq!(BitCount::<9>::new::<3>().range::<u8>(), 0..=0b111);
1578    /// assert_eq!(BitCount::<9>::new::<4>().range::<u8>(), 0..=0b1111);
1579    /// assert_eq!(BitCount::<9>::new::<5>().range::<u8>(), 0..=0b11111);
1580    /// assert_eq!(BitCount::<9>::new::<6>().range::<u8>(), 0..=0b111111);
1581    /// assert_eq!(BitCount::<9>::new::<7>().range::<u8>(), 0..=0b1111111);
1582    /// assert_eq!(BitCount::<9>::new::<8>().range::<u8>(), 0..=0b11111111);
1583    /// // a count that exceeds the type's size is
1584    /// // naturally restricted to that type's maximum range
1585    /// assert_eq!(BitCount::<9>::new::<9>().range::<u8>(), 0..=0b11111111);
1586    /// ```
1587    #[inline]
1588    pub fn range<U: UnsignedInteger>(&self) -> core::ops::RangeInclusive<U> {
1589        match U::ONE.checked_shl(self.bits) {
1590            Some(top) => U::ZERO..=(top - U::ONE),
1591            None => U::ZERO..=U::ALL,
1592        }
1593    }
1594
1595    /// Returns minimum value between ourself and bit count
1596    ///
1597    /// # Example
1598    ///
1599    /// ```
1600    /// use bitstream_io::BitCount;
1601    ///
1602    /// let count = BitCount::<8>::new::<7>();
1603    /// assert_eq!(count.min(6), BitCount::new::<6>());
1604    /// assert_eq!(count.min(8), BitCount::new::<7>());
1605    /// ```
1606    #[inline(always)]
1607    pub fn min(self, bits: u32) -> Self {
1608        // the minimum of ourself and another bit count
1609        // can never exceed our maximum bit count
1610        Self {
1611            bits: self.bits.min(bits),
1612        }
1613    }
1614
1615    /// Returns the minimum value of an unsigned int in this bit count
1616    ///
1617    /// # Example
1618    ///
1619    /// ```
1620    /// use bitstream_io::BitCount;
1621    ///
1622    /// assert_eq!(BitCount::<8>::new::<0>().none::<u8>().into_value(), 0b0);
1623    /// assert_eq!(BitCount::<8>::new::<1>().none::<u8>().into_value(), 0b0);
1624    /// assert_eq!(BitCount::<8>::new::<2>().none::<u8>().into_value(), 0b00);
1625    /// assert_eq!(BitCount::<8>::new::<3>().none::<u8>().into_value(), 0b000);
1626    /// assert_eq!(BitCount::<8>::new::<4>().none::<u8>().into_value(), 0b0000);
1627    /// assert_eq!(BitCount::<8>::new::<5>().none::<u8>().into_value(), 0b00000);
1628    /// assert_eq!(BitCount::<8>::new::<6>().none::<u8>().into_value(), 0b000000);
1629    /// assert_eq!(BitCount::<8>::new::<7>().none::<u8>().into_value(), 0b0000000);
1630    /// assert_eq!(BitCount::<8>::new::<8>().none::<u8>().into_value(), 0b00000000);
1631    /// ```
1632    #[inline(always)]
1633    pub fn none<U: UnsignedInteger>(self) -> CheckedUnsigned<MAX, U> {
1634        CheckedUnsigned {
1635            value: U::ZERO,
1636            count: self,
1637        }
1638    }
1639
1640    /// Returns the maximum value of an unsigned int in this bit count
1641    ///
1642    /// # Example
1643    ///
1644    /// ```
1645    /// use bitstream_io::BitCount;
1646    ///
1647    /// assert_eq!(BitCount::<8>::new::<0>().all::<u8>().into_value(), 0b0);
1648    /// assert_eq!(BitCount::<8>::new::<1>().all::<u8>().into_value(), 0b1);
1649    /// assert_eq!(BitCount::<8>::new::<2>().all::<u8>().into_value(), 0b11);
1650    /// assert_eq!(BitCount::<8>::new::<3>().all::<u8>().into_value(), 0b111);
1651    /// assert_eq!(BitCount::<8>::new::<4>().all::<u8>().into_value(), 0b1111);
1652    /// assert_eq!(BitCount::<8>::new::<5>().all::<u8>().into_value(), 0b11111);
1653    /// assert_eq!(BitCount::<8>::new::<6>().all::<u8>().into_value(), 0b111111);
1654    /// assert_eq!(BitCount::<8>::new::<7>().all::<u8>().into_value(), 0b1111111);
1655    /// assert_eq!(BitCount::<8>::new::<8>().all::<u8>().into_value(), 0b11111111);
1656    /// ```
1657    #[inline(always)]
1658    pub fn all<U: UnsignedInteger>(self) -> CheckedUnsigned<MAX, U> {
1659        CheckedUnsigned {
1660            value: match U::ONE.checked_shl(self.bits) {
1661                Some(top) => top - U::ONE,
1662                None => U::ALL,
1663            },
1664            count: self,
1665        }
1666    }
1667}
1668
1669impl<const MAX: u32> core::convert::TryFrom<u32> for BitCount<MAX> {
1670    type Error = u32;
1671
1672    /// Attempts to convert a `u32` bit count to a `BitCount`
1673    ///
1674    /// Attempting a bit maximum bit count larger than the
1675    /// largest supported type is a compile-time error
1676    ///
1677    /// # Examples
1678    /// ```
1679    /// use bitstream_io::BitCount;
1680    /// use std::convert::TryInto;
1681    ///
1682    /// assert_eq!(8u32.try_into(), Ok(BitCount::<8>::new::<8>()));
1683    /// assert_eq!(9u32.try_into(), Err::<BitCount<8>, _>(9));
1684    /// ```
1685    fn try_from(bits: u32) -> Result<Self, Self::Error> {
1686        (bits <= MAX).then_some(Self { bits }).ok_or(bits)
1687    }
1688}
1689
1690impl<const MAX: u32> core::fmt::Display for BitCount<MAX> {
1691    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1692        core::fmt::Display::fmt(&self.bits, f)
1693    }
1694}
1695
1696impl BitCount<{ u32::MAX }> {
1697    /// Builds a bit count where the maximum bits is unknown.
1698    ///
1699    /// # Example
1700    /// ```
1701    /// use bitstream_io::BitCount;
1702    /// assert_eq!(BitCount::unknown(5), BitCount::<{ u32::MAX }>::new::<5>());
1703    /// ```
1704    pub const fn unknown(bits: u32) -> Self {
1705        Self { bits }
1706    }
1707}
1708
1709#[test]
1710fn test_unknown_bitcount() {
1711    let count = BitCount::unknown(u32::MAX);
1712    assert!(u32::from(count) <= count.max());
1713}
1714
1715impl<const MAX: u32> From<BitCount<MAX>> for u32 {
1716    #[inline(always)]
1717    fn from(BitCount { bits }: BitCount<MAX>) -> u32 {
1718        bits
1719    }
1720}
1721
1722/// A number of bits to be read or written for signed integers, with a known maximum
1723///
1724/// This is closely related to the [`BitCount`] type, but further constrained
1725/// to have a minimum value of 1 - because signed values require at least
1726/// 1 bit for the sign.
1727///
1728/// Let's start with a basic example:
1729///
1730/// ```
1731/// use bitstream_io::{BitRead, BitReader, BigEndian};
1732///
1733/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1734/// let mut r = BitReader::endian(data, BigEndian);
1735/// // our bit count is a 3 bit value
1736/// let count = r.read::<3, u32>().unwrap();
1737/// // that count indicates we need to read 4 bits (0b100)
1738/// assert_eq!(count, 4);
1739/// // read the first 4-bit signed value
1740/// assert_eq!(r.read_var::<i8>(count).unwrap(), 1);
1741/// // read the second 4-bit signed value
1742/// assert_eq!(r.read_var::<i8>(count).unwrap(), -1);
1743/// // read the third 4-bit signed value
1744/// assert_eq!(r.read_var::<i8>(count).unwrap(), 6);
1745/// ```
1746///
1747/// In the preceding example, even though we know `count` is a
1748/// 3 bit value whose maximum value will never be greater than 7,
1749/// the subsequent `read_var` calls have no way to know that.
1750/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1751/// and validate the count is not larger than the `i8` types we're reading
1752/// while also greater than 0 because `i8` requires a sign bit.
1753///
1754/// But we can convert our example to use the `SignedBitCount` type:
1755/// ```
1756/// use bitstream_io::{BitRead, BitReader, BigEndian, SignedBitCount};
1757///
1758/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1759/// let mut r = BitReader::endian(data, BigEndian);
1760/// // our bit count is a 3 bit value with a maximum value of 7
1761/// let count = r.read_count::<0b111>().unwrap();
1762/// // convert that count to a signed bit count,
1763/// // which guarantees its value is greater than 0
1764/// let count = count.signed_count().unwrap();
1765/// // that count indicates we need to read 4 bits (0b100)
1766/// assert_eq!(count, SignedBitCount::<7>::new::<4>());
1767/// // read the first 4-bit value
1768/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 1);
1769/// // read the second 4-bit value
1770/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), -1);
1771/// // read the third 4-bit value
1772/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 6);
1773/// ```
1774///
1775/// Because the [`BitRead::read_signed_counted`] methods know at compile-time
1776/// that the bit count will be larger than 7, that check can be eliminated
1777/// simply by taking advantage of information we already know.
1778///
1779/// Leveraging the `SignedBitCount` type also allows us to reason about
1780/// bit counts in a more formal way, and use checked permutation methods
1781/// to modify them while ensuring they remain constrained by
1782/// the file format's requirements.
1783#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1784pub struct SignedBitCount<const MAX: u32> {
1785    // the whole original bit count
1786    bits: BitCount<MAX>,
1787    // a bit count with one bit removed for the sign
1788    unsigned: BitCount<MAX>,
1789}
1790
1791impl<const MAX: u32> SignedBitCount<MAX> {
1792    /// Builds a signed bit count from a constant number
1793    /// of bits, which must be greater than 0 and
1794    /// not be greater than `MAX`.
1795    ///
1796    /// Intended to be used for defining constants.
1797    ///
1798    /// Use `TryFrom` to conditionally build
1799    /// counts from values at runtime.
1800    ///
1801    /// # Examples
1802    ///
1803    /// ```
1804    /// use bitstream_io::{BitReader, BitRead, BigEndian, SignedBitCount};
1805    /// let data: &[u8] = &[0b111_00000];
1806    /// let mut r = BitReader::endian(data, BigEndian);
1807    /// // reading 3 bits from a stream out of a maximum of 8
1808    /// // doesn't require checking that the bit count is larger
1809    /// // than a u8 at runtime because specifying the maximum of 8
1810    /// // guarantees our bit count will not be larger than 8
1811    /// assert_eq!(r.read_signed_counted::<8, i8>(SignedBitCount::new::<3>()).unwrap(), -1);
1812    /// ```
1813    ///
1814    /// ```rust,compile_fail
1815    /// use bitstream_io::SignedBitCount;
1816    /// // trying to build a count of 10 with a maximum of 8
1817    /// // fails to compile at all
1818    /// let count = SignedBitCount::<8>::new::<10>();
1819    /// ```
1820    ///
1821    /// ```rust,compile_fail
1822    /// use bitstream_io::SignedBitCount;
1823    /// // trying to build a count of 0 also fails to compile
1824    /// let count = SignedBitCount::<8>::new::<0>();
1825    /// ```
1826    pub const fn new<const BITS: u32>() -> Self {
1827        const {
1828            assert!(BITS > 0, "BITS must be > 0");
1829        }
1830
1831        Self {
1832            bits: BitCount::new::<BITS>(),
1833            unsigned: BitCount { bits: BITS - 1 },
1834        }
1835    }
1836
1837    /// Add a number of bits to our count,
1838    /// returning a new count with a new maximum.
1839    ///
1840    /// Returns `None` if the new count goes above our new maximum.
1841    ///
1842    /// # Examples
1843    ///
1844    /// ```
1845    /// use bitstream_io::SignedBitCount;
1846    ///
1847    /// let count = SignedBitCount::<2>::new::<1>();
1848    /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1849    /// assert_eq!(count.checked_add::<3>(2), Some(SignedBitCount::<3>::new::<3>()));
1850    /// // adding 2 to 1 without increasing the max yields None
1851    /// assert_eq!(count.checked_add::<2>(2), None);
1852    /// ```
1853    #[inline]
1854    pub const fn checked_add<const NEW_MAX: u32>(
1855        self,
1856        bits: u32,
1857    ) -> Option<SignedBitCount<NEW_MAX>> {
1858        match self.bits.checked_add(bits) {
1859            Some(bits_new) => match self.unsigned.checked_add(bits) {
1860                Some(unsigned) => Some(SignedBitCount {
1861                    bits: bits_new,
1862                    unsigned,
1863                }),
1864                None => None,
1865            },
1866            None => None,
1867        }
1868    }
1869
1870    /// Subtracts a number of bits from our count,
1871    /// returning a new count with a new maximum.
1872    ///
1873    /// Returns `None` if the new count goes below 1
1874    /// or below our new maximum.
1875    ///
1876    /// # Example
1877    /// ```
1878    /// use bitstream_io::SignedBitCount;
1879    /// let count = SignedBitCount::<5>::new::<5>();
1880    /// // subtracting 1 from 5 yields a new count of 4
1881    /// assert_eq!(count.checked_sub::<5>(1), Some(SignedBitCount::<5>::new::<4>()));
1882    /// // subtracting 6 from 5 yields None
1883    /// assert!(count.checked_sub::<5>(6).is_none());
1884    /// // subtracting 1 with a new maximum of 3 also yields None
1885    /// // because 4 is larger than the maximum of 3
1886    /// assert!(count.checked_sub::<3>(1).is_none());
1887    /// // subtracting 5 from 5 also yields None
1888    /// // because SignedBitCount always requires 1 bit for the sign
1889    /// assert!(count.checked_sub::<5>(5).is_none());
1890    /// ```
1891    #[inline]
1892    pub const fn checked_sub<const NEW_MAX: u32>(
1893        self,
1894        bits: u32,
1895    ) -> Option<SignedBitCount<NEW_MAX>> {
1896        match self.bits.checked_sub(bits) {
1897            Some(bits_new) => match self.unsigned.checked_sub(bits) {
1898                Some(unsigned) => Some(SignedBitCount {
1899                    bits: bits_new,
1900                    unsigned,
1901                }),
1902                None => None,
1903            },
1904            None => None,
1905        }
1906    }
1907
1908    /// Attempt to convert our count to a count with a new
1909    /// bit count and new maximum.
1910    ///
1911    /// Returns `Some(count)` if the updated number of bits
1912    /// is less than or equal to the new maximum
1913    /// and greater than 0.
1914    /// Returns `None` if not.
1915    ///
1916    /// # Examples
1917    /// ```
1918    /// use bitstream_io::SignedBitCount;
1919    ///
1920    /// let count = SignedBitCount::<5>::new::<5>();
1921    /// // muliplying 5 bits by 2 with a new max of 10 is ok
1922    /// assert_eq!(
1923    ///     count.try_map::<10, _>(|i| i.checked_mul(2)),
1924    ///     Some(SignedBitCount::<10>::new::<10>()),
1925    /// );
1926    ///
1927    /// // multiplying 5 bits by 3 with a new max of 10 overflows
1928    /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1929    ///
1930    /// // multiplying 5 bits by 0 results in 0 bits,
1931    /// // which isn't value for a SignedBitCount
1932    /// assert_eq!(count.try_map::<10, _>(|i| Some(i * 0)), None);
1933    /// ```
1934    #[inline]
1935    pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<SignedBitCount<NEW_MAX>>
1936    where
1937        F: FnOnce(u32) -> Option<u32>,
1938    {
1939        self.bits.try_map(f).and_then(|b| b.signed_count())
1940    }
1941
1942    /// Returns our maximum bit count
1943    ///
1944    /// # Example
1945    /// ```
1946    /// use bitstream_io::SignedBitCount;
1947    ///
1948    /// let count = SignedBitCount::<10>::new::<5>();
1949    /// assert_eq!(count.max(), 10);
1950    /// ```
1951    #[inline(always)]
1952    pub const fn max(&self) -> u32 {
1953        MAX
1954    }
1955
1956    /// Returns regular unsigned bit count
1957    ///
1958    /// # Example
1959    ///
1960    /// ```
1961    /// use bitstream_io::{BitCount, SignedBitCount};
1962    ///
1963    /// let signed_count = SignedBitCount::<10>::new::<5>();
1964    /// assert_eq!(signed_count.count(), BitCount::<10>::new::<5>());
1965    /// ```
1966    #[inline(always)]
1967    pub const fn count(&self) -> BitCount<MAX> {
1968        self.bits
1969    }
1970
1971    /// Returns this bit count's range for the given signed type
1972    ///
1973    /// # Example
1974    ///
1975    /// ```
1976    /// use bitstream_io::SignedBitCount;
1977    ///
1978    /// assert_eq!(SignedBitCount::<9>::new::<1>().range::<i8>(), -1..=0);
1979    /// assert_eq!(SignedBitCount::<9>::new::<2>().range::<i8>(), -2..=1);
1980    /// assert_eq!(SignedBitCount::<9>::new::<3>().range::<i8>(), -4..=3);
1981    /// assert_eq!(SignedBitCount::<9>::new::<4>().range::<i8>(), -8..=7);
1982    /// assert_eq!(SignedBitCount::<9>::new::<5>().range::<i8>(), -16..=15);
1983    /// assert_eq!(SignedBitCount::<9>::new::<6>().range::<i8>(), -32..=31);
1984    /// assert_eq!(SignedBitCount::<9>::new::<7>().range::<i8>(), -64..=63);
1985    /// assert_eq!(SignedBitCount::<9>::new::<8>().range::<i8>(), -128..=127);
1986    /// // a count that exceeds the type's size is
1987    /// // naturally restricted to that type's maximum range
1988    /// assert_eq!(SignedBitCount::<9>::new::<9>().range::<i8>(), -128..=127);
1989    /// ```
1990    pub fn range<S: SignedInteger>(&self) -> core::ops::RangeInclusive<S> {
1991        // a bit of a hack to get around the somewhat restrictive
1992        // SignedInteger trait I've created for myself
1993
1994        if self.bits.bits < S::BITS_SIZE {
1995            (!S::ZERO << self.unsigned.bits)..=((S::ONE << self.unsigned.bits) - S::ONE)
1996        } else {
1997            S::Unsigned::ZERO.as_negative(S::BITS_SIZE)..=(S::Unsigned::ALL >> 1).as_non_negative()
1998        }
1999    }
2000}
2001
2002impl<const MAX: u32> core::fmt::Display for SignedBitCount<MAX> {
2003    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2004        core::fmt::Display::fmt(&self.bits, f)
2005    }
2006}
2007
2008impl<const MAX: u32> core::convert::TryFrom<BitCount<MAX>> for SignedBitCount<MAX> {
2009    type Error = ();
2010
2011    #[inline]
2012    fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
2013        count.signed_count().ok_or(())
2014    }
2015}
2016
2017impl<const MAX: u32> core::convert::TryFrom<u32> for SignedBitCount<MAX> {
2018    type Error = u32;
2019
2020    #[inline]
2021    fn try_from(count: u32) -> Result<Self, Self::Error> {
2022        BitCount::<MAX>::try_from(count).and_then(|b| b.signed_count().ok_or(count))
2023    }
2024}
2025
2026impl<const MAX: u32> From<SignedBitCount<MAX>> for u32 {
2027    #[inline(always)]
2028    fn from(
2029        SignedBitCount {
2030            bits: BitCount { bits },
2031            ..
2032        }: SignedBitCount<MAX>,
2033    ) -> u32 {
2034        bits
2035    }
2036}
2037
2038/// An error when converting a value to a [`Checked`] struct
2039#[derive(Copy, Clone, Debug)]
2040pub enum CheckedError {
2041    /// Excessive bits for type
2042    ExcessiveBits,
2043    /// Excessive value for bits
2044    ExcessiveValue,
2045}
2046
2047impl core::error::Error for CheckedError {}
2048
2049impl core::fmt::Display for CheckedError {
2050    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2051        match self {
2052            Self::ExcessiveBits => core::fmt::Display::fmt("excessive bits for type written", f),
2053            Self::ExcessiveValue => core::fmt::Display::fmt("excessive value for bits written", f),
2054        }
2055    }
2056}
2057
2058impl From<CheckedError> for io::Error {
2059    #[inline]
2060    fn from(error: CheckedError) -> Self {
2061        match error {
2062            CheckedError::ExcessiveBits => io::Error::new(
2063                io::ErrorKind::InvalidInput,
2064                "excessive bits for type written",
2065            ),
2066            CheckedError::ExcessiveValue => io::Error::new(
2067                io::ErrorKind::InvalidInput,
2068                "excessive value for bits written",
2069            ),
2070        }
2071    }
2072}
2073
2074/// A type for eliminating redundant validation when writing
2075///
2076/// Normally, when writing a value, not only must the number of bits
2077/// must be checked against the type being written
2078/// (e.g. writing 9 bits from a `u8` is always an error),
2079/// but the value must also be checked against the number of bits
2080/// (e.g. writing a value of 2 in 1 bit is always an error).
2081///
2082/// But when the value's range can be checked in advance,
2083/// the write-time check can be skipped through the use
2084/// of the [`BitWrite::write_checked`] method.
2085#[derive(Copy, Clone, Debug)]
2086pub struct Checked<C, T> {
2087    count: C,
2088    value: T,
2089}
2090
2091impl<C, T> Checked<C, T> {
2092    /// Returns our bit count and value
2093    #[inline]
2094    pub fn into_count_value(self) -> (C, T) {
2095        (self.count, self.value)
2096    }
2097
2098    /// Returns our value
2099    #[inline]
2100    pub fn into_value(self) -> T {
2101        self.value
2102    }
2103}
2104
2105impl<C, T> AsRef<T> for Checked<C, T> {
2106    fn as_ref(&self) -> &T {
2107        &self.value
2108    }
2109}
2110
2111/// An unsigned type with a verified value
2112pub type CheckedUnsigned<const MAX: u32, T> = Checked<BitCount<MAX>, T>;
2113
2114impl<const MAX: u32, U: UnsignedInteger> Checkable for CheckedUnsigned<MAX, U> {
2115    #[inline]
2116    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2117        // a naive default implementation
2118        writer.write_unsigned_counted(self.count, self.value)
2119    }
2120
2121    #[inline]
2122    fn written_bits(&self) -> u32 {
2123        self.count.bits
2124    }
2125}
2126
2127impl<const MAX: u32, U: UnsignedInteger> CheckablePrimitive for CheckedUnsigned<MAX, U> {
2128    type CountType = BitCount<MAX>;
2129
2130    #[inline]
2131    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self> {
2132        reader
2133            .read_unsigned_counted(count)
2134            .map(|value| Self { value, count })
2135    }
2136}
2137
2138impl<const MAX: u32, U: UnsignedInteger> private::Checkable for CheckedUnsigned<MAX, U> {
2139    fn write_endian<E, W>(
2140        self,
2141        writer: &mut W,
2142        queue_value: &mut u8,
2143        queue_bits: &mut u32,
2144    ) -> io::Result<()>
2145    where
2146        E: private::Endianness,
2147        W: io::Write,
2148    {
2149        E::write_bits_checked(writer, queue_value, queue_bits, self)
2150    }
2151}
2152
2153impl<const MAX: u32, U: UnsignedInteger> CheckedUnsigned<MAX, U> {
2154    /// Returns our value if it fits in the given number of bits
2155    ///
2156    /// # Example
2157    ///
2158    /// ```
2159    /// use bitstream_io::{BitCount, CheckedUnsigned, CheckedError};
2160    ///
2161    /// // a value of 7 fits into a 3 bit count
2162    /// assert!(CheckedUnsigned::<8, u8>::new(3, 0b111).is_ok());
2163    ///
2164    /// // a value of 8 does not fit into a 3 bit count
2165    /// assert!(matches!(
2166    ///     CheckedUnsigned::<8, u8>::new(3, 0b1000),
2167    ///     Err(CheckedError::ExcessiveValue),
2168    /// ));
2169    ///
2170    /// // a bit count of 9 is too large for u8
2171    /// assert!(matches!(
2172    ///     CheckedUnsigned::<9, _>::new(9, 1u8),
2173    ///     Err(CheckedError::ExcessiveBits),
2174    /// ));
2175    /// ```
2176    #[inline]
2177    pub fn new(count: impl TryInto<BitCount<MAX>>, value: U) -> Result<Self, CheckedError> {
2178        let count @ BitCount { bits } =
2179            count.try_into().map_err(|_| CheckedError::ExcessiveBits)?;
2180
2181        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2182            if bits == 0 {
2183                Ok(Self {
2184                    count,
2185                    value: U::ZERO,
2186                })
2187            } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
2188                Ok(Self { count, value })
2189            } else {
2190                Err(CheckedError::ExcessiveValue)
2191            }
2192        } else {
2193            Err(CheckedError::ExcessiveBits)
2194        }
2195    }
2196
2197    /// Returns our value if it fits in the given number of const bits
2198    ///
2199    /// # Examples
2200    ///
2201    /// ```
2202    /// use bitstream_io::{CheckedUnsigned, CheckedError};
2203    ///
2204    /// // a value of 7 fits into a 3 bit count
2205    /// assert!(CheckedUnsigned::<8, u8>::new_fixed::<3>(0b111).is_ok());
2206    ///
2207    /// // a value of 8 does not fit into a 3 bit count
2208    /// assert!(matches!(
2209    ///     CheckedUnsigned::<8, u8>::new_fixed::<3>(0b1000),
2210    ///     Err(CheckedError::ExcessiveValue),
2211    /// ));
2212    /// ```
2213    ///
2214    /// ```compile_fail
2215    /// use bitstream_io::{BitCount, CheckedUnsigned};
2216    ///
2217    /// // a bit count of 9 is too large for u8
2218    ///
2219    /// // because this is checked at compile-time,
2220    /// // it does not compile at all
2221    /// let c = CheckedUnsigned::<16, u8>::new_fixed::<9>(1);
2222    /// ```
2223    pub fn new_fixed<const BITS: u32>(value: U) -> Result<Self, CheckedError> {
2224        const {
2225            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2226        }
2227
2228        if BITS == 0 {
2229            Ok(Self {
2230                count: BitCount::new::<0>(),
2231                value: U::ZERO,
2232            })
2233        } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2234            Ok(Self {
2235                // whether BITS is larger than MAX is checked here
2236                count: BitCount::new::<BITS>(),
2237                value,
2238            })
2239        } else {
2240            Err(CheckedError::ExcessiveValue)
2241        }
2242    }
2243}
2244
2245/// A fixed number of bits to be consumed or written
2246///
2247/// Analagous to [`BitCount`], this is a zero-sized type
2248/// whose value is fixed at compile-time and cannot be changed.
2249///
2250/// # Example
2251///
2252/// ```
2253/// use bitstream_io::{
2254///     BigEndian, BitRead, BitReader, BitWrite, BitWriter, CheckedUnsignedFixed, FixedBitCount,
2255/// };
2256///
2257/// type FourBits = CheckedUnsignedFixed<4, u8>;
2258///
2259/// let input: &[u8] = &[0b0001_1111, 0b0110_1001];
2260/// let mut r = BitReader::endian(input, BigEndian);
2261///
2262/// // read 4, 4-bit values
2263/// let v1 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2264/// let v2 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2265/// let v3 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2266/// let v4 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2267///
2268/// assert_eq!(v1.into_value(), 0b0001);
2269/// assert_eq!(v2.into_value(), 0b1111);
2270/// assert_eq!(v3.into_value(), 0b0110);
2271/// assert_eq!(v4.into_value(), 0b1001);
2272///
2273/// // write those same values back to disk
2274/// let mut w = BitWriter::endian(vec![], BigEndian);
2275/// w.write_checked(v1).unwrap();
2276/// w.write_checked(v2).unwrap();
2277/// w.write_checked(v3).unwrap();
2278/// w.write_checked(v4).unwrap();
2279///
2280/// // ensure they're the same
2281/// assert_eq!(w.into_writer().as_slice(), input);
2282/// ```
2283#[derive(Copy, Clone, Debug)]
2284pub struct FixedBitCount<const BITS: u32>;
2285
2286impl<const BITS: u32> From<FixedBitCount<BITS>> for BitCount<BITS> {
2287    fn from(_count: FixedBitCount<BITS>) -> Self {
2288        BitCount::new::<BITS>()
2289    }
2290}
2291
2292impl<const BITS: u32, const MAX: u32> core::convert::TryFrom<BitCount<MAX>>
2293    for FixedBitCount<BITS>
2294{
2295    type Error = BitCount<MAX>;
2296
2297    fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
2298        (count.bits == BITS).then_some(FixedBitCount).ok_or(count)
2299    }
2300}
2301
2302/// An unsigned type with a verified value for a fixed number of bits
2303pub type CheckedUnsignedFixed<const BITS: u32, T> = Checked<FixedBitCount<BITS>, T>;
2304
2305impl<const BITS: u32, U: UnsignedInteger> CheckedUnsignedFixed<BITS, U> {
2306    /// Returns our checked value if it fits in the given number of const bits
2307    ///
2308    /// # Examples
2309    ///
2310    /// ```
2311    /// use bitstream_io::{CheckedUnsignedFixed, CheckedError};
2312    ///
2313    /// // a value of 7 fits into a maximum of 3 bits
2314    /// assert!(CheckedUnsignedFixed::<3, u8>::new_fixed(0b111).is_ok());
2315    ///
2316    /// // a value of 8 does not fit into a maximum of 3 bits
2317    /// assert!(matches!(
2318    ///     CheckedUnsignedFixed::<3, u8>::new_fixed(0b1000),
2319    ///     Err(CheckedError::ExcessiveValue),
2320    /// ));
2321    /// ```
2322    ///
2323    /// ```compile_fail
2324    /// use bitstream_io::CheckedUnsignedFixed;
2325    ///
2326    /// // a bit count of 9 is too large for u8
2327    ///
2328    /// // because this is checked at compile-time,
2329    /// // it does not compile at all
2330    /// let c = CheckedUnsignedFixed::<9, u8>::new_fixed(1);
2331    /// ```
2332    pub fn new_fixed(value: U) -> Result<Self, CheckedError> {
2333        const {
2334            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2335        }
2336
2337        if BITS == 0 {
2338            Ok(Self {
2339                count: FixedBitCount,
2340                value: U::ZERO,
2341            })
2342        } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2343            Ok(Self {
2344                count: FixedBitCount,
2345                value,
2346            })
2347        } else {
2348            Err(CheckedError::ExcessiveValue)
2349        }
2350    }
2351}
2352
2353impl<const BITS: u32, U: UnsignedInteger> Checkable for CheckedUnsignedFixed<BITS, U> {
2354    #[inline]
2355    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2356        // a naive default implementation
2357        writer.write_unsigned::<BITS, _>(self.value)
2358    }
2359
2360    #[inline]
2361    fn written_bits(&self) -> u32 {
2362        BITS
2363    }
2364}
2365
2366impl<const BITS: u32, U: UnsignedInteger> private::Checkable for CheckedUnsignedFixed<BITS, U> {
2367    fn write_endian<E, W>(
2368        self,
2369        writer: &mut W,
2370        queue_value: &mut u8,
2371        queue_bits: &mut u32,
2372    ) -> io::Result<()>
2373    where
2374        E: private::Endianness,
2375        W: io::Write,
2376    {
2377        E::write_bits_checked(
2378            writer,
2379            queue_value,
2380            queue_bits,
2381            Checked {
2382                value: self.value,
2383                count: self.count.into(),
2384            },
2385        )
2386    }
2387}
2388
2389impl<const BITS: u32, U: UnsignedInteger> CheckablePrimitive for CheckedUnsignedFixed<BITS, U> {
2390    type CountType = FixedBitCount<BITS>;
2391
2392    fn read<R: BitRead + ?Sized>(reader: &mut R, count: FixedBitCount<BITS>) -> io::Result<Self> {
2393        Ok(Self {
2394            value: reader.read_unsigned::<BITS, _>()?,
2395            count,
2396        })
2397    }
2398}
2399
2400/// A signed type with a verified value
2401pub type CheckedSigned<const MAX: u32, T> = Checked<SignedBitCount<MAX>, T>;
2402
2403impl<const MAX: u32, S: SignedInteger> Checkable for CheckedSigned<MAX, S> {
2404    #[inline]
2405    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2406        // a naive default implementation
2407        writer.write_signed_counted(self.count, self.value)
2408    }
2409
2410    #[inline]
2411    fn written_bits(&self) -> u32 {
2412        self.count.bits.into()
2413    }
2414}
2415
2416impl<const MAX: u32, S: SignedInteger> CheckablePrimitive for CheckedSigned<MAX, S> {
2417    type CountType = SignedBitCount<MAX>;
2418
2419    #[inline]
2420    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self> {
2421        reader
2422            .read_signed_counted(count)
2423            .map(|value| Self { value, count })
2424    }
2425}
2426
2427impl<const MAX: u32, S: SignedInteger> private::Checkable for CheckedSigned<MAX, S> {
2428    #[inline]
2429    fn write_endian<E, W>(
2430        self,
2431        writer: &mut W,
2432        queue_value: &mut u8,
2433        queue_bits: &mut u32,
2434    ) -> io::Result<()>
2435    where
2436        E: private::Endianness,
2437        W: io::Write,
2438    {
2439        E::write_signed_bits_checked(writer, queue_value, queue_bits, self)
2440    }
2441}
2442
2443impl<const MAX: u32, S: SignedInteger> CheckedSigned<MAX, S> {
2444    /// Returns our value if it fits in the given number of bits
2445    ///
2446    /// # Example
2447    ///
2448    /// ```
2449    /// use bitstream_io::{SignedBitCount, CheckedSigned, CheckedError};
2450    ///
2451    /// // a value of 3 fits into a 3 bit count
2452    /// assert!(CheckedSigned::<8, _>::new(3, 3i8).is_ok());
2453    ///
2454    /// // a value of 4 does not fit into a 3 bit count
2455    /// assert!(matches!(
2456    ///     CheckedSigned::<8, _>::new(3, 4i8),
2457    ///     Err(CheckedError::ExcessiveValue),
2458    /// ));
2459    ///
2460    /// // a bit count of 9 is too large for i8
2461    /// assert!(matches!(
2462    ///     CheckedSigned::<9, _>::new(9, 1i8),
2463    ///     Err(CheckedError::ExcessiveBits),
2464    /// ));
2465    /// ```
2466    #[inline]
2467    pub fn new(count: impl TryInto<SignedBitCount<MAX>>, value: S) -> Result<Self, CheckedError> {
2468        let count @ SignedBitCount {
2469            bits: BitCount { bits },
2470            unsigned: BitCount {
2471                bits: unsigned_bits,
2472            },
2473        } = count.try_into().map_err(|_| CheckedError::ExcessiveBits)?;
2474
2475        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2476            if bits == S::BITS_SIZE
2477                || (((S::ZERO - S::ONE) << unsigned_bits) <= value
2478                    && value < (S::ONE << unsigned_bits))
2479            {
2480                Ok(Self { count, value })
2481            } else {
2482                Err(CheckedError::ExcessiveValue)
2483            }
2484        } else {
2485            Err(CheckedError::ExcessiveBits)
2486        }
2487    }
2488
2489    /// Returns our value if it fits in the given number of const bits
2490    ///
2491    /// # Examples
2492    ///
2493    /// ```
2494    /// use bitstream_io::{CheckedSigned, CheckedError};
2495    ///
2496    /// // a value of 3 fits into a 3 bit count
2497    /// assert!(CheckedSigned::<8, i8>::new_fixed::<3>(3).is_ok());
2498    ///
2499    /// // a value of 4 does not fit into a 3 bit count
2500    /// assert!(matches!(
2501    ///     CheckedSigned::<8, i8>::new_fixed::<3>(4),
2502    ///     Err(CheckedError::ExcessiveValue),
2503    /// ));
2504    /// ```
2505    ///
2506    /// ```compile_fail
2507    /// use bitstream_io::{BitCount, CheckedSigned};
2508    ///
2509    /// // a bit count of 9 is too large for i8
2510    ///
2511    /// // because this is checked at compile-time,
2512    /// // it does not compile at all
2513    /// let c = CheckedSigned::<16, i8>::new_fixed::<9>(1);
2514    /// ```
2515    pub fn new_fixed<const BITS: u32>(value: S) -> Result<Self, CheckedError> {
2516        const {
2517            assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
2518        }
2519
2520        if BITS == S::BITS_SIZE
2521            || (((S::ZERO - S::ONE) << (BITS - 1)) <= value && value < (S::ONE << (BITS - 1)))
2522        {
2523            Ok(Self {
2524                count: SignedBitCount::new::<BITS>(),
2525                value,
2526            })
2527        } else {
2528            Err(CheckedError::ExcessiveValue)
2529        }
2530    }
2531}
2532
2533/// A fixed number of bits to be consumed or written
2534///
2535/// Analagous to [`SignedBitCount`], this is a zero-sized type
2536/// whose value is fixed at compile-time and cannot be changed.
2537///
2538/// # Example
2539///
2540/// ```
2541/// use bitstream_io::{
2542///     BigEndian, BitRead, BitReader, BitWrite, BitWriter,
2543///     CheckedSignedFixed, FixedSignedBitCount,
2544/// };
2545///
2546/// type FourBits = CheckedSignedFixed<4, i8>;
2547///
2548/// let input: &[u8] = &[0b0001_1111, 0b0110_1001];
2549/// let mut r = BitReader::endian(input, BigEndian);
2550///
2551/// // read 4, 4-bit values
2552/// let v1 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2553/// let v2 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2554/// let v3 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2555/// let v4 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2556///
2557/// assert_eq!(v1.into_value(), 1);
2558/// assert_eq!(v2.into_value(), -1);
2559/// assert_eq!(v3.into_value(), 6);
2560/// assert_eq!(v4.into_value(), -7);
2561///
2562/// // write those same values back to disk
2563/// let mut w = BitWriter::endian(vec![], BigEndian);
2564/// w.write_checked(v1).unwrap();
2565/// w.write_checked(v2).unwrap();
2566/// w.write_checked(v3).unwrap();
2567/// w.write_checked(v4).unwrap();
2568///
2569/// // ensure they're the same
2570/// assert_eq!(w.into_writer().as_slice(), input);
2571/// ```
2572#[derive(Copy, Clone, Debug)]
2573pub struct FixedSignedBitCount<const BITS: u32>;
2574
2575impl<const BITS: u32> From<FixedSignedBitCount<BITS>> for SignedBitCount<BITS> {
2576    fn from(_count: FixedSignedBitCount<BITS>) -> Self {
2577        SignedBitCount::new::<BITS>()
2578    }
2579}
2580
2581impl<const BITS: u32, const MAX: u32> core::convert::TryFrom<SignedBitCount<MAX>>
2582    for FixedSignedBitCount<BITS>
2583{
2584    type Error = SignedBitCount<MAX>;
2585
2586    fn try_from(count: SignedBitCount<MAX>) -> Result<Self, Self::Error> {
2587        (count.bits.bits == BITS)
2588            .then_some(FixedSignedBitCount)
2589            .ok_or(count)
2590    }
2591}
2592
2593/// A signed type with a verified value for a fixed number of bits
2594pub type CheckedSignedFixed<const BITS: u32, T> = Checked<FixedSignedBitCount<BITS>, T>;
2595
2596impl<const BITS: u32, S: SignedInteger> CheckedSignedFixed<BITS, S> {
2597    /// Returns our checked value if it fits in the given number of const bits
2598    ///
2599    /// # Examples
2600    ///
2601    /// ```
2602    /// use bitstream_io::{SignedBitCount, CheckedSignedFixed, CheckedError};
2603    ///
2604    /// // a value of 3 fits into a 3 bit count
2605    /// assert!(CheckedSignedFixed::<3, _>::new_fixed(3i8).is_ok());
2606    ///
2607    /// // a value of 4 does not fit into a 3 bit count
2608    /// assert!(matches!(
2609    ///     CheckedSignedFixed::<3, _>::new_fixed(4i8),
2610    ///     Err(CheckedError::ExcessiveValue),
2611    /// ));
2612    /// ```
2613    ///
2614    /// ```compile_fail
2615    /// use bitstream_io::CheckedSignedFixed;
2616    ///
2617    /// // a bit count of 9 is too large for i8
2618    ///
2619    /// // because this is checked at compile-time,
2620    /// // it does not compile at all
2621    /// let c = CheckedSignedFixed::<9, _>::new_fixed(1i8);
2622    /// ```
2623    pub fn new_fixed(value: S) -> Result<Self, CheckedError> {
2624        const {
2625            assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
2626        }
2627
2628        if BITS == S::BITS_SIZE
2629            || (((S::ZERO - S::ONE) << (BITS - 1)) <= value && value < (S::ONE << (BITS - 1)))
2630        {
2631            Ok(Self {
2632                count: FixedSignedBitCount,
2633                value,
2634            })
2635        } else {
2636            Err(CheckedError::ExcessiveValue)
2637        }
2638    }
2639}
2640impl<const BITS: u32, S: SignedInteger> Checkable for CheckedSignedFixed<BITS, S> {
2641    #[inline]
2642    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2643        // a naive default implementation
2644        writer.write_signed::<BITS, _>(self.value)
2645    }
2646
2647    #[inline]
2648    fn written_bits(&self) -> u32 {
2649        BITS
2650    }
2651}
2652
2653impl<const BITS: u32, S: SignedInteger> private::Checkable for CheckedSignedFixed<BITS, S> {
2654    #[inline]
2655    fn write_endian<E, W>(
2656        self,
2657        writer: &mut W,
2658        queue_value: &mut u8,
2659        queue_bits: &mut u32,
2660    ) -> io::Result<()>
2661    where
2662        E: private::Endianness,
2663        W: io::Write,
2664    {
2665        E::write_signed_bits_checked(
2666            writer,
2667            queue_value,
2668            queue_bits,
2669            CheckedSigned {
2670                value: self.value,
2671                count: self.count.into(),
2672            },
2673        )
2674    }
2675}
2676
2677impl<const BITS: u32, S: SignedInteger> CheckablePrimitive for CheckedSignedFixed<BITS, S> {
2678    type CountType = FixedSignedBitCount<BITS>;
2679
2680    fn read<R: BitRead + ?Sized>(
2681        reader: &mut R,
2682        count: FixedSignedBitCount<BITS>,
2683    ) -> io::Result<Self> {
2684        Ok(Self {
2685            value: reader.read_signed::<BITS, _>()?,
2686            count,
2687        })
2688    }
2689}
2690
2691/// A trait for writable types whose values can be validated
2692///
2693/// Ordinarily, when writing a value to a stream with a given
2694/// number of bits, the value must be validated to ensure
2695/// it will fit within that number of bits.
2696///
2697/// # Example 1
2698///
2699/// ```
2700/// use bitstream_io::{BitWrite, BitWriter, BigEndian};
2701///
2702/// let mut w = BitWriter::endian(vec![], BigEndian);
2703///
2704/// // writing a value of 2 in 1 bit is always an error
2705/// // which is checked here at write-time
2706/// assert!(w.write::<1, u8>(2).is_err());
2707/// ```
2708///
2709/// But if the value can be checked beforehand,
2710/// it doesn't need to be checked at write-time.
2711///
2712/// # Example 2
2713///
2714/// ```
2715/// use bitstream_io::{BitWrite, BitWriter, BigEndian, CheckedUnsigned};
2716///
2717/// let mut w = BitWriter::endian(vec![], BigEndian);
2718///
2719/// // writing a value of 1 in 1 bit is ok
2720/// // and we're checking that validity at this stage
2721/// let value = CheckedUnsigned::<1, u8>::new_fixed::<1>(1).unwrap();
2722///
2723/// // because we've pre-validated the value beforehand,
2724/// // it doesn't need to be checked again here
2725/// // (though the write itself may still fail)
2726/// assert!(w.write_checked(value).is_ok());
2727/// ```
2728///
2729pub trait Checkable: private::Checkable + Sized {
2730    /// Write our value to the given stream
2731    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()>;
2732
2733    /// The number of written bits
2734    fn written_bits(&self) -> u32;
2735}
2736
2737/// A trait for readable types whose bit counts can be saved
2738///
2739/// Because the intent of reading checkable values is
2740/// to avoid validating their values when being written,
2741/// implementing the [`Checkable`] trait is required.
2742pub trait CheckablePrimitive: Checkable {
2743    /// Our bit count type for reading
2744    type CountType;
2745
2746    /// Reads our value from the given stream
2747    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self>;
2748}
2749
2750/// Big-endian, or most significant bits first
2751#[derive(Copy, Clone, Debug)]
2752pub struct BigEndian;
2753
2754/// Big-endian, or most significant bits first
2755pub type BE = BigEndian;
2756
2757impl BigEndian {
2758    // checked in the sense that we've verified
2759    // the output type is large enough to hold the
2760    // requested number of bits
2761    #[inline]
2762    fn read_bits_checked<const MAX: u32, R, U>(
2763        reader: &mut R,
2764        queue: &mut u8,
2765        queue_bits: &mut u32,
2766        BitCount { bits }: BitCount<MAX>,
2767    ) -> io::Result<U>
2768    where
2769        R: io::Read,
2770        U: UnsignedInteger,
2771    {
2772        // reads a whole value with the given number of
2773        // bytes in our endianness, where the number of bytes
2774        // must be less than or equal to the type's size in bytes
2775        #[inline(always)]
2776        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
2777        where
2778            R: io::Read,
2779            U: UnsignedInteger,
2780        {
2781            let mut buf = U::buffer();
2782            reader
2783                .read_exact(&mut buf.as_mut()[(mem::size_of::<U>() - bytes)..])
2784                .map(|()| U::from_be_bytes(buf))
2785        }
2786
2787        if bits <= *queue_bits {
2788            // all bits in queue, so no byte needed
2789            let value = queue.shr_default(u8::BITS_SIZE - bits);
2790            *queue = queue.shl_default(bits);
2791            *queue_bits -= bits;
2792            Ok(U::from_u8(value))
2793        } else {
2794            // at least one byte needed
2795
2796            // bits needed beyond what's in the queue
2797            let needed_bits = bits - *queue_bits;
2798
2799            match (needed_bits / 8, needed_bits % 8) {
2800                (0, needed) => {
2801                    // only one additional byte needed,
2802                    // which we share between our returned value
2803                    // and the bit queue
2804                    let next_byte = read_byte(reader)?;
2805
2806                    Ok(U::from_u8(
2807                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
2808                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
2809                        ),
2810                    )
2811                    .shl_default(needed)
2812                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
2813                }
2814                (bytes, 0) => {
2815                    // exact number of bytes needed beyond what's
2816                    // available in the queue
2817                    // so read a whole value from the reader
2818                    // and prepend what's left of our queue onto it
2819
2820                    Ok(U::from_u8(
2821                        mem::take(queue).shr_default(u8::BITS_SIZE - mem::take(queue_bits)),
2822                    )
2823                    .shl_default(needed_bits)
2824                        | read_bytes(reader, bytes as usize)?)
2825                }
2826                (bytes, needed) => {
2827                    // read a whole value from the reader
2828                    // prepend what's in the queue at the front of it
2829                    // *and* append a partial byte at the end of it
2830                    // while also updating the queue and its bit count
2831
2832                    let whole: U = read_bytes(reader, bytes as usize)?;
2833                    let next_byte = read_byte(reader)?;
2834
2835                    Ok(U::from_u8(
2836                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
2837                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
2838                        ),
2839                    )
2840                    .shl_default(needed_bits)
2841                        | whole.shl_default(needed)
2842                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
2843                }
2844            }
2845        }
2846    }
2847}
2848
2849impl Endianness for BigEndian {}
2850
2851impl private::Endianness for BigEndian {
2852    #[inline]
2853    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
2854        *queue_value = (*queue_value << 1) | u8::from(bit);
2855        *queue_bits = (*queue_bits + 1) % 8;
2856        (*queue_bits == 0).then(|| mem::take(queue_value))
2857    }
2858
2859    #[inline]
2860    fn read_bits<const MAX: u32, R, U>(
2861        reader: &mut R,
2862        queue_value: &mut u8,
2863        queue_bits: &mut u32,
2864        count @ BitCount { bits }: BitCount<MAX>,
2865    ) -> io::Result<U>
2866    where
2867        R: io::Read,
2868        U: UnsignedInteger,
2869    {
2870        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2871            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
2872        } else {
2873            Err(io::Error::new(
2874                io::ErrorKind::InvalidInput,
2875                "excessive bits for type read",
2876            ))
2877        }
2878    }
2879
2880    #[inline]
2881    fn read_bits_fixed<const BITS: u32, R, U>(
2882        reader: &mut R,
2883        queue_value: &mut u8,
2884        queue_bits: &mut u32,
2885    ) -> io::Result<U>
2886    where
2887        R: io::Read,
2888        U: UnsignedInteger,
2889    {
2890        const {
2891            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
2892        }
2893
2894        Self::read_bits_checked::<BITS, R, U>(
2895            reader,
2896            queue_value,
2897            queue_bits,
2898            BitCount::new::<BITS>(),
2899        )
2900    }
2901
2902    // checked in the sense that we've verified
2903    // the input type is large enough to hold the
2904    // requested number of bits and that the value is
2905    // not too large for those bits
2906    #[inline]
2907    fn write_bits_checked<const MAX: u32, W, U>(
2908        writer: &mut W,
2909        queue_value: &mut u8,
2910        queue_bits: &mut u32,
2911        CheckedUnsigned {
2912            count: BitCount { bits },
2913            value,
2914        }: CheckedUnsigned<MAX, U>,
2915    ) -> io::Result<()>
2916    where
2917        W: io::Write,
2918        U: UnsignedInteger,
2919    {
2920        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
2921        where
2922            W: io::Write,
2923            U: UnsignedInteger,
2924        {
2925            let buf = U::to_be_bytes(value);
2926            writer.write_all(&buf.as_ref()[(mem::size_of::<U>() - bytes)..])
2927        }
2928
2929        // the amount of available bits in the queue
2930        let available_bits = u8::BITS_SIZE - *queue_bits;
2931
2932        if bits < available_bits {
2933            // all bits fit in queue, so no write needed
2934            *queue_value = queue_value.shl_default(bits) | U::to_u8(value);
2935            *queue_bits += bits;
2936            Ok(())
2937        } else {
2938            // at least one byte needs to be written
2939
2940            // bits beyond what can fit in the queue
2941            let excess_bits = bits - available_bits;
2942
2943            match (excess_bits / 8, excess_bits % 8) {
2944                (0, excess) => {
2945                    // only one byte to be written,
2946                    // while the excess bits are shared
2947                    // between the written byte and the bit queue
2948
2949                    *queue_bits = excess;
2950
2951                    write_byte(
2952                        writer,
2953                        mem::replace(
2954                            queue_value,
2955                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
2956                        )
2957                        .shl_default(available_bits)
2958                            | U::to_u8(value.shr_default(excess)),
2959                    )
2960                }
2961                (bytes, 0) => {
2962                    // no excess bytes beyond what can fit the queue
2963                    // so write a whole byte and
2964                    // the remainder of the whole value
2965
2966                    *queue_bits = 0;
2967
2968                    write_byte(
2969                        writer.by_ref(),
2970                        mem::take(queue_value).shl_default(available_bits)
2971                            | U::to_u8(value.shr_default(bytes * 8)),
2972                    )?;
2973
2974                    write_bytes(writer, bytes as usize, value)
2975                }
2976                (bytes, excess) => {
2977                    // write what's in the queue along
2978                    // with the head of our whole value,
2979                    // write the middle section of our whole value,
2980                    // while also replacing the queue with
2981                    // the tail of our whole value
2982
2983                    *queue_bits = excess;
2984
2985                    write_byte(
2986                        writer.by_ref(),
2987                        mem::replace(
2988                            queue_value,
2989                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
2990                        )
2991                        .shl_default(available_bits)
2992                            | U::to_u8(value.shr_default(excess + bytes * 8)),
2993                    )?;
2994
2995                    write_bytes(writer, bytes as usize, value.shr_default(excess))
2996                }
2997            }
2998        }
2999    }
3000
3001    fn write_signed_bits_checked<const MAX: u32, W, S>(
3002        writer: &mut W,
3003        queue_value: &mut u8,
3004        queue_bits: &mut u32,
3005        value: CheckedSigned<MAX, S>,
3006    ) -> io::Result<()>
3007    where
3008        W: io::Write,
3009        S: SignedInteger,
3010    {
3011        let (
3012            SignedBitCount {
3013                bits: BitCount { bits },
3014                unsigned,
3015            },
3016            value,
3017        ) = value.into_count_value();
3018
3019        if let Some(b) = Self::push_bit_flush(queue_value, queue_bits, value.is_negative()) {
3020            write_byte(writer.by_ref(), b)?;
3021        }
3022        Self::write_bits_checked(
3023            writer,
3024            queue_value,
3025            queue_bits,
3026            Checked {
3027                value: if value.is_negative() {
3028                    value.as_negative(bits)
3029                } else {
3030                    value.as_non_negative()
3031                },
3032                count: unsigned,
3033            },
3034        )
3035    }
3036
3037    #[inline]
3038    fn pop_bit_refill<R>(
3039        reader: &mut R,
3040        queue_value: &mut u8,
3041        queue_bits: &mut u32,
3042    ) -> io::Result<bool>
3043    where
3044        R: io::Read,
3045    {
3046        Ok(if *queue_bits == 0 {
3047            let value = read_byte(reader)?;
3048            let msb = value & u8::MSB_BIT;
3049            *queue_value = value << 1;
3050            *queue_bits = u8::BITS_SIZE - 1;
3051            msb
3052        } else {
3053            let msb = *queue_value & u8::MSB_BIT;
3054            *queue_value <<= 1;
3055            *queue_bits -= 1;
3056            msb
3057        } != 0)
3058    }
3059
3060    #[inline]
3061    fn pop_unary<const STOP_BIT: u8, R>(
3062        reader: &mut R,
3063        queue_value: &mut u8,
3064        queue_bits: &mut u32,
3065    ) -> io::Result<u32>
3066    where
3067        R: io::Read,
3068    {
3069        const {
3070            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
3071        }
3072
3073        match STOP_BIT {
3074            0 => find_unary(
3075                reader,
3076                queue_value,
3077                queue_bits,
3078                |v| v.leading_ones(),
3079                |q| *q,
3080                |v, b| v.checked_shl(b),
3081            ),
3082            1 => find_unary(
3083                reader,
3084                queue_value,
3085                queue_bits,
3086                |v| v.leading_zeros(),
3087                |_| u8::BITS_SIZE,
3088                |v, b| v.checked_shl(b),
3089            ),
3090            _ => unreachable!(),
3091        }
3092    }
3093
3094    #[inline]
3095    fn read_signed_counted<const MAX: u32, R, S>(
3096        r: &mut R,
3097        SignedBitCount {
3098            bits: BitCount { bits },
3099            unsigned,
3100        }: SignedBitCount<MAX>,
3101    ) -> io::Result<S>
3102    where
3103        R: BitRead,
3104        S: SignedInteger,
3105    {
3106        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
3107            let is_negative = r.read_bit()?;
3108            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
3109            Ok(if is_negative {
3110                unsigned.as_negative(bits)
3111            } else {
3112                unsigned.as_non_negative()
3113            })
3114        } else {
3115            Err(io::Error::new(
3116                io::ErrorKind::InvalidInput,
3117                "excessive bits for type read",
3118            ))
3119        }
3120    }
3121
3122    fn read_bytes<const CHUNK_SIZE: usize, R>(
3123        reader: &mut R,
3124        queue_value: &mut u8,
3125        queue_bits: u32,
3126        buf: &mut [u8],
3127    ) -> io::Result<()>
3128    where
3129        R: io::Read,
3130    {
3131        if queue_bits == 0 {
3132            reader.read_exact(buf)
3133        } else {
3134            let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3135
3136            for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
3137                let input_chunk = &mut input_chunk[0..output_chunk.len()];
3138                reader.read_exact(input_chunk)?;
3139
3140                // shift down each byte in our input to eventually
3141                // accomodate the contents of the bit queue
3142                // and make that our output
3143                output_chunk
3144                    .iter_mut()
3145                    .zip(input_chunk.iter())
3146                    .for_each(|(o, i)| {
3147                        *o = i >> queue_bits;
3148                    });
3149
3150                // include leftover bits from the next byte
3151                // shifted to the top
3152                output_chunk[1..]
3153                    .iter_mut()
3154                    .zip(input_chunk.iter())
3155                    .for_each(|(o, i)| {
3156                        *o |= *i << (u8::BITS_SIZE - queue_bits);
3157                    });
3158
3159                // finally, prepend the queue's contents
3160                // to the first byte in the chunk
3161                // while replacing those contents
3162                // with the final byte of the input
3163                output_chunk[0] |= mem::replace(
3164                    queue_value,
3165                    input_chunk.last().unwrap() << (u8::BITS_SIZE - queue_bits),
3166                );
3167            }
3168
3169            Ok(())
3170        }
3171    }
3172
3173    fn write_bytes<const CHUNK_SIZE: usize, W>(
3174        writer: &mut W,
3175        queue_value: &mut u8,
3176        queue_bits: u32,
3177        buf: &[u8],
3178    ) -> io::Result<()>
3179    where
3180        W: io::Write,
3181    {
3182        if queue_bits == 0 {
3183            writer.write_all(buf)
3184        } else {
3185            let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3186
3187            for input_chunk in buf.chunks(CHUNK_SIZE) {
3188                let output_chunk = &mut output_chunk[0..input_chunk.len()];
3189
3190                output_chunk
3191                    .iter_mut()
3192                    .zip(input_chunk.iter())
3193                    .for_each(|(o, i)| {
3194                        *o = i >> queue_bits;
3195                    });
3196
3197                output_chunk[1..]
3198                    .iter_mut()
3199                    .zip(input_chunk.iter())
3200                    .for_each(|(o, i)| {
3201                        *o |= *i << (u8::BITS_SIZE - queue_bits);
3202                    });
3203
3204                output_chunk[0] |= mem::replace(
3205                    queue_value,
3206                    input_chunk.last().unwrap() & (u8::ALL >> (u8::BITS_SIZE - queue_bits)),
3207                ) << (u8::BITS_SIZE - queue_bits);
3208
3209                writer.write_all(output_chunk)?;
3210            }
3211
3212            Ok(())
3213        }
3214    }
3215
3216    #[inline(always)]
3217    fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
3218        P::from_be_bytes(buf)
3219    }
3220
3221    #[inline(always)]
3222    fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
3223        p.to_be_bytes()
3224    }
3225
3226    #[inline]
3227    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
3228    where
3229        R: BitRead,
3230        V: Primitive,
3231    {
3232        let mut buffer = V::buffer();
3233        r.read_bytes(buffer.as_mut())?;
3234        Ok(V::from_be_bytes(buffer))
3235    }
3236
3237    #[inline]
3238    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
3239    where
3240        W: BitWrite,
3241        V: Primitive,
3242    {
3243        w.write_bytes(value.to_be_bytes().as_ref())
3244    }
3245}
3246
3247/// Little-endian, or least significant bits first
3248#[derive(Copy, Clone, Debug)]
3249pub struct LittleEndian;
3250
3251/// Little-endian, or least significant bits first
3252pub type LE = LittleEndian;
3253
3254impl LittleEndian {
3255    // checked in the sense that we've verified
3256    // the output type is large enough to hold the
3257    // requested number of bits
3258    #[inline]
3259    fn read_bits_checked<const MAX: u32, R, U>(
3260        reader: &mut R,
3261        queue: &mut u8,
3262        queue_bits: &mut u32,
3263        BitCount { bits }: BitCount<MAX>,
3264    ) -> io::Result<U>
3265    where
3266        R: io::Read,
3267        U: UnsignedInteger,
3268    {
3269        // reads a whole value with the given number of
3270        // bytes in our endianness, where the number of bytes
3271        // must be less than or equal to the type's size in bytes
3272        #[inline(always)]
3273        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
3274        where
3275            R: io::Read,
3276            U: UnsignedInteger,
3277        {
3278            let mut buf = U::buffer();
3279            reader
3280                .read_exact(&mut buf.as_mut()[0..bytes])
3281                .map(|()| U::from_le_bytes(buf))
3282        }
3283
3284        if bits <= *queue_bits {
3285            // all bits in queue, so no byte needed
3286            let value = *queue & u8::ALL.shr_default(u8::BITS_SIZE - bits);
3287            *queue = queue.shr_default(bits);
3288            *queue_bits -= bits;
3289            Ok(U::from_u8(value))
3290        } else {
3291            // at least one byte needed
3292
3293            // bits needed beyond what's in the queue
3294            let needed_bits = bits - *queue_bits;
3295
3296            match (needed_bits / 8, needed_bits % 8) {
3297                (0, needed) => {
3298                    // only one additional byte needed,
3299                    // which we share between our returned value
3300                    // and the bit queue
3301                    let next_byte = read_byte(reader)?;
3302
3303                    Ok(
3304                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
3305                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
3306                                << mem::replace(queue_bits, u8::BITS_SIZE - needed)),
3307                    )
3308                }
3309                (bytes, 0) => {
3310                    // exact number of bytes needed beyond what's
3311                    // available in the queue
3312
3313                    // so read a whole value from the reader
3314                    // and prepend what's left of our queue onto it
3315
3316                    Ok(U::from_u8(mem::take(queue))
3317                        | (read_bytes::<R, U>(reader, bytes as usize)? << mem::take(queue_bits)))
3318                }
3319                (bytes, needed) => {
3320                    // read a whole value from the reader
3321                    // prepend what's in the queue at the front of it
3322                    // *and* append a partial byte at the end of it
3323                    // while also updating the queue and its bit count
3324
3325                    let whole: U = read_bytes(reader, bytes as usize)?;
3326                    let next_byte = read_byte(reader)?;
3327
3328                    Ok(
3329                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
3330                            | (whole << *queue_bits)
3331                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
3332                                << (mem::replace(queue_bits, u8::BITS_SIZE - needed) + bytes * 8)),
3333                    )
3334                }
3335            }
3336        }
3337    }
3338}
3339
3340impl Endianness for LittleEndian {}
3341
3342impl private::Endianness for LittleEndian {
3343    #[inline]
3344    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
3345        *queue_value |= u8::from(bit) << *queue_bits;
3346        *queue_bits = (*queue_bits + 1) % 8;
3347        (*queue_bits == 0).then(|| mem::take(queue_value))
3348    }
3349
3350    #[inline]
3351    fn read_bits<const MAX: u32, R, U>(
3352        reader: &mut R,
3353        queue_value: &mut u8,
3354        queue_bits: &mut u32,
3355        count @ BitCount { bits }: BitCount<MAX>,
3356    ) -> io::Result<U>
3357    where
3358        R: io::Read,
3359        U: UnsignedInteger,
3360    {
3361        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
3362            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
3363        } else {
3364            Err(io::Error::new(
3365                io::ErrorKind::InvalidInput,
3366                "excessive bits for type read",
3367            ))
3368        }
3369    }
3370
3371    #[inline]
3372    fn read_bits_fixed<const BITS: u32, R, U>(
3373        reader: &mut R,
3374        queue_value: &mut u8,
3375        queue_bits: &mut u32,
3376    ) -> io::Result<U>
3377    where
3378        R: io::Read,
3379        U: UnsignedInteger,
3380    {
3381        const {
3382            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
3383        }
3384
3385        Self::read_bits_checked::<BITS, R, U>(
3386            reader,
3387            queue_value,
3388            queue_bits,
3389            BitCount::new::<BITS>(),
3390        )
3391    }
3392
3393    // checked in the sense that we've verified
3394    // the input type is large enough to hold the
3395    // requested number of bits and that the value is
3396    // not too large for those bits
3397    #[inline]
3398    fn write_bits_checked<const MAX: u32, W, U>(
3399        writer: &mut W,
3400        queue_value: &mut u8,
3401        queue_bits: &mut u32,
3402        CheckedUnsigned {
3403            count: BitCount { bits },
3404            value,
3405        }: CheckedUnsigned<MAX, U>,
3406    ) -> io::Result<()>
3407    where
3408        W: io::Write,
3409        U: UnsignedInteger,
3410    {
3411        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
3412        where
3413            W: io::Write,
3414            U: UnsignedInteger,
3415        {
3416            let buf = U::to_le_bytes(value);
3417            writer.write_all(&buf.as_ref()[0..bytes])
3418        }
3419
3420        // the amount of available bits in the queue
3421        let available_bits = u8::BITS_SIZE - *queue_bits;
3422
3423        if bits < available_bits {
3424            // all bits fit in queue, so no write needed
3425            *queue_value |= U::to_u8(value.shl_default(*queue_bits));
3426            *queue_bits += bits;
3427            Ok(())
3428        } else {
3429            // at least one byte needs to be written
3430
3431            // bits beyond what can fit in the queue
3432            let excess_bits = bits - available_bits;
3433
3434            match (excess_bits / 8, excess_bits % 8) {
3435                (0, excess) => {
3436                    // only one byte to be written,
3437                    // while the excess bits are shared
3438                    // between the written byte and the bit queue
3439
3440                    write_byte(
3441                        writer,
3442                        mem::replace(queue_value, U::to_u8(value.shr_default(available_bits)))
3443                            | U::to_u8(
3444                                (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
3445                            ),
3446                    )
3447                }
3448                (bytes, 0) => {
3449                    // no excess bytes beyond what can fit the queue
3450                    // so write a whole byte and
3451                    // the remainder of the whole value
3452
3453                    write_byte(
3454                        writer.by_ref(),
3455                        mem::take(queue_value)
3456                            | U::to_u8((value << mem::take(queue_bits)) & U::from_u8(u8::ALL)),
3457                    )?;
3458
3459                    write_bytes(writer, bytes as usize, value >> available_bits)
3460                }
3461                (bytes, excess) => {
3462                    // write what's in the queue along
3463                    // with the head of our whole value,
3464                    // write the middle section of our whole value,
3465                    // while also replacing the queue with
3466                    // the tail of our whole value
3467
3468                    write_byte(
3469                        writer.by_ref(),
3470                        mem::replace(
3471                            queue_value,
3472                            U::to_u8(value.shr_default(available_bits + bytes * 8)),
3473                        ) | U::to_u8(
3474                            (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
3475                        ),
3476                    )?;
3477
3478                    write_bytes(writer, bytes as usize, value >> available_bits)
3479                }
3480            }
3481        }
3482    }
3483
3484    fn write_signed_bits_checked<const MAX: u32, W, S>(
3485        writer: &mut W,
3486        queue_value: &mut u8,
3487        queue_bits: &mut u32,
3488        value: CheckedSigned<MAX, S>,
3489    ) -> io::Result<()>
3490    where
3491        W: io::Write,
3492        S: SignedInteger,
3493    {
3494        // little-endian
3495        let (
3496            SignedBitCount {
3497                bits: BitCount { bits },
3498                unsigned,
3499            },
3500            value,
3501        ) = value.into_count_value();
3502
3503        Self::write_bits_checked(
3504            writer.by_ref(),
3505            queue_value,
3506            queue_bits,
3507            Checked {
3508                value: if value.is_negative() {
3509                    value.as_negative(bits)
3510                } else {
3511                    value.as_non_negative()
3512                },
3513                count: unsigned,
3514            },
3515        )?;
3516        match Self::push_bit_flush(queue_value, queue_bits, value.is_negative()) {
3517            Some(b) => write_byte(writer, b),
3518            None => Ok(()),
3519        }
3520    }
3521
3522    #[inline]
3523    fn pop_bit_refill<R>(
3524        reader: &mut R,
3525        queue_value: &mut u8,
3526        queue_bits: &mut u32,
3527    ) -> io::Result<bool>
3528    where
3529        R: io::Read,
3530    {
3531        Ok(if *queue_bits == 0 {
3532            let value = read_byte(reader)?;
3533            let lsb = value & u8::LSB_BIT;
3534            *queue_value = value >> 1;
3535            *queue_bits = u8::BITS_SIZE - 1;
3536            lsb
3537        } else {
3538            let lsb = *queue_value & u8::LSB_BIT;
3539            *queue_value >>= 1;
3540            *queue_bits -= 1;
3541            lsb
3542        } != 0)
3543    }
3544
3545    #[inline]
3546    fn pop_unary<const STOP_BIT: u8, R>(
3547        reader: &mut R,
3548        queue_value: &mut u8,
3549        queue_bits: &mut u32,
3550    ) -> io::Result<u32>
3551    where
3552        R: io::Read,
3553    {
3554        const {
3555            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
3556        }
3557
3558        match STOP_BIT {
3559            0 => find_unary(
3560                reader,
3561                queue_value,
3562                queue_bits,
3563                |v| v.trailing_ones(),
3564                |q| *q,
3565                |v, b| v.checked_shr(b),
3566            ),
3567            1 => find_unary(
3568                reader,
3569                queue_value,
3570                queue_bits,
3571                |v| v.trailing_zeros(),
3572                |_| u8::BITS_SIZE,
3573                |v, b| v.checked_shr(b),
3574            ),
3575            _ => unreachable!(),
3576        }
3577    }
3578
3579    #[inline]
3580    fn read_signed_counted<const MAX: u32, R, S>(
3581        r: &mut R,
3582        SignedBitCount {
3583            bits: BitCount { bits },
3584            unsigned,
3585        }: SignedBitCount<MAX>,
3586    ) -> io::Result<S>
3587    where
3588        R: BitRead,
3589        S: SignedInteger,
3590    {
3591        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
3592            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
3593            let is_negative = r.read_bit()?;
3594            Ok(if is_negative {
3595                unsigned.as_negative(bits)
3596            } else {
3597                unsigned.as_non_negative()
3598            })
3599        } else {
3600            Err(io::Error::new(
3601                io::ErrorKind::InvalidInput,
3602                "excessive bits for type read",
3603            ))
3604        }
3605    }
3606
3607    fn read_bytes<const CHUNK_SIZE: usize, R>(
3608        reader: &mut R,
3609        queue_value: &mut u8,
3610        queue_bits: u32,
3611        buf: &mut [u8],
3612    ) -> io::Result<()>
3613    where
3614        R: io::Read,
3615    {
3616        if queue_bits == 0 {
3617            reader.read_exact(buf)
3618        } else {
3619            let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3620
3621            for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
3622                let input_chunk = &mut input_chunk[0..output_chunk.len()];
3623                reader.read_exact(input_chunk)?;
3624
3625                output_chunk
3626                    .iter_mut()
3627                    .zip(input_chunk.iter())
3628                    .for_each(|(o, i)| {
3629                        *o = i << queue_bits;
3630                    });
3631
3632                output_chunk[1..]
3633                    .iter_mut()
3634                    .zip(input_chunk.iter())
3635                    .for_each(|(o, i)| {
3636                        *o |= i >> (u8::BITS_SIZE - queue_bits);
3637                    });
3638
3639                output_chunk[0] |= mem::replace(
3640                    queue_value,
3641                    input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
3642                );
3643            }
3644
3645            Ok(())
3646        }
3647    }
3648
3649    fn write_bytes<const CHUNK_SIZE: usize, W>(
3650        writer: &mut W,
3651        queue_value: &mut u8,
3652        queue_bits: u32,
3653        buf: &[u8],
3654    ) -> io::Result<()>
3655    where
3656        W: io::Write,
3657    {
3658        if queue_bits == 0 {
3659            writer.write_all(buf)
3660        } else {
3661            let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3662
3663            for input_chunk in buf.chunks(CHUNK_SIZE) {
3664                let output_chunk = &mut output_chunk[0..input_chunk.len()];
3665
3666                output_chunk
3667                    .iter_mut()
3668                    .zip(input_chunk.iter())
3669                    .for_each(|(o, i)| {
3670                        *o = i << queue_bits;
3671                    });
3672
3673                output_chunk[1..]
3674                    .iter_mut()
3675                    .zip(input_chunk.iter())
3676                    .for_each(|(o, i)| {
3677                        *o |= i >> (u8::BITS_SIZE - queue_bits);
3678                    });
3679
3680                output_chunk[0] |= mem::replace(
3681                    queue_value,
3682                    input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
3683                );
3684
3685                writer.write_all(output_chunk)?;
3686            }
3687
3688            Ok(())
3689        }
3690    }
3691
3692    #[inline(always)]
3693    fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
3694        P::from_le_bytes(buf)
3695    }
3696
3697    #[inline(always)]
3698    fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
3699        p.to_le_bytes()
3700    }
3701
3702    #[inline]
3703    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
3704    where
3705        R: BitRead,
3706        V: Primitive,
3707    {
3708        let mut buffer = V::buffer();
3709        r.read_bytes(buffer.as_mut())?;
3710        Ok(V::from_le_bytes(buffer))
3711    }
3712
3713    #[inline]
3714    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
3715    where
3716        W: BitWrite,
3717        V: Primitive,
3718    {
3719        w.write_bytes(value.to_le_bytes().as_ref())
3720    }
3721}
3722
3723#[inline]
3724fn find_unary<R>(
3725    reader: &mut R,
3726    queue_value: &mut u8,
3727    queue_bits: &mut u32,
3728    leading_bits: impl Fn(u8) -> u32,
3729    max_bits: impl Fn(&mut u32) -> u32,
3730    checked_shift: impl Fn(u8, u32) -> Option<u8>,
3731) -> io::Result<u32>
3732where
3733    R: io::Read,
3734{
3735    let mut acc = 0;
3736
3737    loop {
3738        match leading_bits(*queue_value) {
3739            bits if bits == max_bits(queue_bits) => {
3740                // all bits exhausted
3741                // fetch another byte and keep going
3742                acc += *queue_bits;
3743                *queue_value = read_byte(reader.by_ref())?;
3744                *queue_bits = u8::BITS_SIZE;
3745            }
3746            bits => match checked_shift(*queue_value, bits + 1) {
3747                Some(value) => {
3748                    // fetch part of source byte
3749                    *queue_value = value;
3750                    *queue_bits -= bits + 1;
3751                    break Ok(acc + bits);
3752                }
3753                None => {
3754                    // fetch all of source byte
3755                    *queue_value = 0;
3756                    *queue_bits = 0;
3757                    break Ok(acc + bits);
3758                }
3759            },
3760        }
3761    }
3762}