Skip to main content

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