Skip to main content

irox_bits/
stdwrappers.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2025 IROX Contributors
3//
4
5use core::ops::{Deref, DerefMut};
6
7///
8/// Wraps a borrowed value and provides implementations of [`Bits`] and [`MutBits`] where applicable.
9pub enum BitsWrapper<'a, T> {
10    Owned(T),
11    Borrowed(&'a mut T),
12}
13impl<B> Deref for BitsWrapper<'_, B> {
14    type Target = B;
15
16    fn deref(&self) -> &Self::Target {
17        match self {
18            BitsWrapper::Borrowed(v) => v,
19            BitsWrapper::Owned(v) => v,
20        }
21    }
22}
23impl<B> DerefMut for BitsWrapper<'_, B> {
24    fn deref_mut(&mut self) -> &mut Self::Target {
25        match self {
26            BitsWrapper::Borrowed(v) => v,
27            BitsWrapper::Owned(v) => v,
28        }
29    }
30}
31
32#[cfg(feature = "std")]
33mod stds {
34    use crate::{Bits, BitsWrapper, Error, MutBits};
35
36    impl<T> Bits for BitsWrapper<'_, T>
37    where
38        T: std::io::Read,
39    {
40        fn next_u8(&mut self) -> Result<Option<u8>, Error> {
41            let mut byte: u8 = 0;
42            let read = self.read(core::slice::from_mut(&mut byte))?;
43            if read < 1 {
44                return Ok(None);
45            }
46            Ok(Some(byte))
47        }
48
49        fn read_some_into<R: MutBits>(&mut self, buf: &mut R) -> Result<usize, Error> {
50            let mut b = [0u8; 4096];
51            let read = self.read(&mut b)?;
52            buf.write_all_bytes(b.get(0..read).unwrap_or_default())?;
53            Ok(read)
54        }
55    }
56
57    impl<T> MutBits for BitsWrapper<'_, T>
58    where
59        T: std::io::Write,
60    {
61        fn write_u8(&mut self, val: u8) -> Result<(), Error> {
62            Ok(self.write_all(&[val])?)
63        }
64
65        fn write_all_bytes(&mut self, val: &[u8]) -> Result<(), Error> {
66            Ok(self.write_all(val)?)
67        }
68    }
69
70    impl<T> std::io::Read for BitsWrapper<'_, T>
71    where
72        T: Bits,
73    {
74        fn read(&mut self, mut buf: &mut [u8]) -> std::io::Result<usize> {
75            Ok(match self {
76                BitsWrapper::Owned(o) => Bits::read_some_into(o, &mut buf)?,
77                BitsWrapper::Borrowed(b) => Bits::read_some_into(*b, &mut buf)?,
78            })
79        }
80    }
81}