pub trait BitWriter {
Show 16 methods
// Required methods
fn write_bit(&mut self, bit: bool) -> Result<()>;
fn write_u8(&mut self, value: u8) -> Result<()>;
fn write_i8(&mut self, value: i8) -> Result<()>;
fn write_u16(&mut self, value: u16) -> Result<()>;
fn write_i16(&mut self, value: i16) -> Result<()>;
fn write_u32(&mut self, value: u32) -> Result<()>;
fn write_i32(&mut self, value: i32) -> Result<()>;
fn write_f32(&mut self, value: f32) -> Result<()>;
fn write_u64(&mut self, value: u64) -> Result<()>;
fn write_i64(&mut self, value: i64) -> Result<()>;
fn write_f64(&mut self, value: f64) -> Result<()>;
fn write_bits(&mut self, bits: u32, value: u64) -> Result<()>;
fn write_signed_bits(&mut self, bits: u32, value: i64) -> Result<()>;
fn unaligned_bits(&self) -> u32;
fn write_bytes(&mut self, buf: &[u8]) -> Result<()>;
fn flush(&mut self) -> Result<()>;
}Expand description
Write bits in a given endian order
The BitWriter trait provides methods for writing data bit-by-bit to any type
that implements std::io::Write. It supports writing individual bits, standard
data types (integers, floats), and arbitrary bit sequences.
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_bit(true).unwrap();
writer.write_u8(0xff).unwrap();
writer.write_bits(4, 0xA).unwrap();
writer.flush().unwrap();Required Methods§
Sourcefn write_bit(&mut self, bit: bool) -> Result<()>
fn write_bit(&mut self, bit: bool) -> Result<()>
Write a single bit
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_bit(true).unwrap();
writer.write_bit(false).unwrap();
writer.flush().unwrap();
}
assert_eq!(buffer, &[0b01]);Sourcefn write_u8(&mut self, value: u8) -> Result<()>
fn write_u8(&mut self, value: u8) -> Result<()>
Write 8 bits as a byte
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_u8(0xAB).unwrap();
writer.flush().unwrap();
}
assert_eq!(buffer, &[0xAB]);Sourcefn write_i8(&mut self, value: i8) -> Result<()>
fn write_i8(&mut self, value: i8) -> Result<()>
Write 8 bits as a signed byte
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_i8(-42).unwrap();
writer.flush().unwrap();
}
assert_eq!(buffer, &[(-42i8) as u8]);Sourcefn write_u16(&mut self, value: u16) -> Result<()>
fn write_u16(&mut self, value: u16) -> Result<()>
Write 16 bits as an unsigned short
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_u16(0x1234).unwrap();
writer.flush().unwrap();
}
// Little endian: least significant byte first
assert_eq!(buffer, &[0x34, 0x12]);Sourcefn write_i16(&mut self, value: i16) -> Result<()>
fn write_i16(&mut self, value: i16) -> Result<()>
Write 16 bits as a signed short
§Examples
use bitter::{BitWriter, BigEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = BigEndianWriter::new(&mut buffer);
writer.write_i16(-1000).unwrap();
writer.flush().unwrap();
}
// Big endian: most significant byte first
let expected = (-1000i16).to_be_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_u32(&mut self, value: u32) -> Result<()>
fn write_u32(&mut self, value: u32) -> Result<()>
Write 32 bits as an unsigned int
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_u32(0xDEADBEEF).unwrap();
writer.flush().unwrap();
}
assert_eq!(buffer, &[0xEF, 0xBE, 0xAD, 0xDE]);Sourcefn write_i32(&mut self, value: i32) -> Result<()>
fn write_i32(&mut self, value: i32) -> Result<()>
Write 32 bits as a signed int
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_i32(-123456).unwrap();
writer.flush().unwrap();
}
let expected = (-123456i32).to_le_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_f32(&mut self, value: f32) -> Result<()>
fn write_f32(&mut self, value: f32) -> Result<()>
Write 32 bits as a floating point
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_f32(3.14159).unwrap();
writer.flush().unwrap();
}
let expected = 3.14159f32.to_le_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_u64(&mut self, value: u64) -> Result<()>
fn write_u64(&mut self, value: u64) -> Result<()>
Write 64 bits as an unsigned long
§Examples
use bitter::{BitWriter, BigEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = BigEndianWriter::new(&mut buffer);
writer.write_u64(0x123456789ABCDEF0).unwrap();
writer.flush().unwrap();
}
let expected = 0x123456789ABCDEF0u64.to_be_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_i64(&mut self, value: i64) -> Result<()>
fn write_i64(&mut self, value: i64) -> Result<()>
Write 64 bits as a signed long
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_i64(-9876543210).unwrap();
writer.flush().unwrap();
}
let expected = (-9876543210i64).to_le_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_f64(&mut self, value: f64) -> Result<()>
fn write_f64(&mut self, value: f64) -> Result<()>
Write 64 bits as a floating point
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_f64(2.718281828459045).unwrap();
writer.flush().unwrap();
}
let expected = 2.718281828459045f64.to_le_bytes();
assert_eq!(buffer, expected.as_slice());Sourcefn write_bits(&mut self, bits: u32, value: u64) -> Result<()>
fn write_bits(&mut self, bits: u32, value: u64) -> Result<()>
Write an arbitrary number of bits (up to and including 64) as unsigned value
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
// Write 12 bits with value 0xABC
writer.write_bits(12, 0xABC).unwrap();
writer.flush().unwrap();
}
// 0xABC = 2748 = 1010 1011 1100 in binary
// In little endian, this gets packed as: [0xBC, 0x0A]
assert_eq!(buffer, &[0xBC, 0x0A]);Sourcefn write_signed_bits(&mut self, bits: u32, value: i64) -> Result<()>
fn write_signed_bits(&mut self, bits: u32, value: i64) -> Result<()>
Write an arbitrary number of bits (up to and including 64) as signed value
The value is sign-extended or truncated to fit the specified number of bits.
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
// Write -3 in 4 bits (will be 0b1101 in two's complement)
writer.write_signed_bits(4, -3).unwrap();
writer.flush().unwrap();
}
// -3 in 4 bits = 0b1101, padded with zeros to complete the byte
assert_eq!(buffer, &[0x0D]); // 0b0000_1101Sourcefn unaligned_bits(&self) -> u32
fn unaligned_bits(&self) -> u32
Returns the number of bits written in the current partial byte
When the writer is byte-aligned, this returns 0. Otherwise, it returns the number of bits (1-7) already written in the current byte.
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
let mut writer = LittleEndianWriter::new(&mut buffer);
assert_eq!(writer.unaligned_bits(), 0); // Byte-aligned
writer.write_bit(true).unwrap();
assert_eq!(writer.unaligned_bits(), 1); // 1 bit in current byte
writer.write_bits(7, 0x7F).unwrap();
assert_eq!(writer.unaligned_bits(), 0); // Aligned again (1+7=8)Sourcefn write_bytes(&mut self, buf: &[u8]) -> Result<()>
fn write_bytes(&mut self, buf: &[u8]) -> Result<()>
Write the provided buffer as bytes
This method writes the entire buffer as a sequence of bytes. If the writer is not currently byte-aligned, the bytes will be written starting from the current bit position, potentially spanning across byte boundaries.
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
// Write some bytes
let data = [0xAB, 0xCD, 0xEF];
writer.write_bytes(&data).unwrap();
writer.flush().unwrap();
}
assert_eq!(buffer, &[0xAB, 0xCD, 0xEF]);§Byte Alignment
When not byte-aligned, bytes are written bit by bit:
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_bit(true).unwrap(); // Not byte-aligned
writer.write_bytes(&[0xFF]).unwrap();
writer.flush().unwrap();
}
// The 0xFF byte gets shifted due to the initial bit
assert_eq!(buffer, &[0xFF, 0x01]); // 0xFF shifted + remaining bitSourcefn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Flush any buffered bits, padding with zeros if necessary
This method ensures all pending bits are written to the underlying writer. If there are partial bits remaining, they are zero-padded to complete the current byte.
§Zero Padding Behavior
Important: When flushing partial bytes, the remaining bits are always padded with zeros. This behavior can affect data interpretation if you’re not expecting it:
- Little-endian: Zero bits are added to the high-order positions
- Big-endian: Zero bits are added to the low-order positions
§Examples
use bitter::{BitWriter, LittleEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = LittleEndianWriter::new(&mut buffer);
writer.write_bits(3, 0b101).unwrap(); // Write 3 bits
// Buffer is still empty until we flush
writer.flush().unwrap(); // Force write with zero padding
}
assert_eq!(buffer.len(), 1);
assert_eq!(buffer[0], 0b00000101); // 3 bits + 5 zero-padded bitsFor big-endian, padding appears in different positions:
use bitter::{BitWriter, BigEndianWriter};
let mut buffer = Vec::new();
{
let mut writer = BigEndianWriter::new(&mut buffer);
writer.write_bits(3, 0b101).unwrap(); // Write 3 bits
writer.flush().unwrap(); // Force write with zero padding
}
assert_eq!(buffer.len(), 1);
assert_eq!(buffer[0], 0b10100000); // 3 bits + 5 zero-padded bits