196 lines
4.6 KiB
Rust
196 lines
4.6 KiB
Rust
#![no_std]
|
|
|
|
pub struct ReadWriteBuf<const N: usize> {
|
|
buffer: [u8; N],
|
|
read_cursor: usize,
|
|
write_cursor: usize,
|
|
full: bool,
|
|
}
|
|
|
|
impl<const N: usize> Default for ReadWriteBuf<N> {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl<const N: usize> ReadWriteBuf<N> {
|
|
pub fn new() -> ReadWriteBuf<N> {
|
|
if N == 0 {
|
|
panic!("N cannot be zero");
|
|
}
|
|
|
|
ReadWriteBuf {
|
|
buffer: [0; N],
|
|
read_cursor: 0,
|
|
write_cursor: 0,
|
|
full: false,
|
|
}
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.read_cursor == self.write_cursor && !self.full
|
|
}
|
|
|
|
pub fn is_full(&self) -> bool {
|
|
self.full
|
|
}
|
|
|
|
pub fn for_reading(&mut self) -> Option<&mut [u8]> {
|
|
let (start, stop) = if self.read_cursor < self.write_cursor {
|
|
(self.read_cursor, self.write_cursor)
|
|
} else if !self.full {
|
|
(self.read_cursor, N)
|
|
} else {
|
|
return None;
|
|
};
|
|
|
|
Some(&mut self.buffer[start..stop])
|
|
}
|
|
|
|
pub fn for_writing(&self) -> Option<&[u8]> {
|
|
let (start, stop) = if self.write_cursor < self.read_cursor {
|
|
(self.write_cursor, self.read_cursor)
|
|
} else if self.full || self.read_cursor < self.write_cursor {
|
|
(self.write_cursor, N)
|
|
} else {
|
|
return None;
|
|
};
|
|
|
|
Some(&self.buffer[start..stop])
|
|
}
|
|
|
|
pub fn advance_read(&mut self, count: usize) {
|
|
self.read_cursor = (self.read_cursor + count) % N;
|
|
if self.read_cursor == self.write_cursor && count > 0 {
|
|
self.full = true;
|
|
}
|
|
}
|
|
|
|
pub fn advance_write(&mut self, count: usize) {
|
|
self.write_cursor = (self.write_cursor + count) % N;
|
|
if count > 0 {
|
|
self.full = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::ReadWriteBuf;
|
|
|
|
#[test]
|
|
fn read_exact_length_works() {
|
|
let mut buf = ReadWriteBuf::<10>::new();
|
|
assert!(buf.is_empty());
|
|
assert!(buf.for_writing().is_none());
|
|
|
|
let read_into = buf.for_reading().unwrap();
|
|
assert_eq!(read_into.len(), 10);
|
|
buf.advance_read(10);
|
|
|
|
assert!(buf.is_full());
|
|
assert_eq!(buf.read_cursor, buf.write_cursor);
|
|
|
|
let write_from = buf.for_writing().unwrap();
|
|
assert_eq!(write_from.len(), 10);
|
|
buf.advance_write(10);
|
|
|
|
assert!(!buf.full);
|
|
assert_eq!(buf.read_cursor, buf.write_cursor);
|
|
|
|
let read_from = buf.for_reading().unwrap();
|
|
assert_eq!(read_from.len(), 10);
|
|
|
|
assert!(buf.for_writing().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn from_0_0_reads_whole_len() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
|
|
let slice = buf.for_reading().unwrap();
|
|
assert_eq!(slice.len(), 16);
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_0_reads_11() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_read(5);
|
|
|
|
let slice = buf.for_reading().unwrap();
|
|
assert_eq!(slice.len(), 11);
|
|
}
|
|
|
|
#[test]
|
|
fn from_0_5_reads_5() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_write(5);
|
|
|
|
let slice = buf.for_reading().unwrap();
|
|
assert_eq!(slice.len(), 5);
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_5_reads_11() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_read(5);
|
|
buf.advance_write(5);
|
|
|
|
let slice = buf.for_reading().unwrap();
|
|
assert_eq!(slice.len(), 11);
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_5_full_reads_0() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_write(5);
|
|
buf.advance_read(5);
|
|
|
|
assert!(buf.for_reading().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn from_0_0_writes_0() {
|
|
let buf = ReadWriteBuf::<16>::new();
|
|
|
|
assert!(buf.for_writing().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_0_writes_5() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_read(5);
|
|
|
|
let slice = buf.for_writing().unwrap();
|
|
assert_eq!(slice.len(), 5);
|
|
}
|
|
|
|
#[test]
|
|
fn from_0_5_writes_11() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_write(5);
|
|
|
|
let slice = buf.for_writing().unwrap();
|
|
assert_eq!(slice.len(), 11);
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_5_writes_0() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_read(5);
|
|
buf.advance_write(5);
|
|
|
|
assert!(buf.for_writing().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn from_5_5_full_writes_11() {
|
|
let mut buf = ReadWriteBuf::<16>::new();
|
|
buf.advance_write(5);
|
|
buf.advance_read(5);
|
|
|
|
let slice = buf.for_writing().unwrap();
|
|
assert_eq!(slice.len(), 11);
|
|
}
|
|
}
|