Skip to content

Commit

Permalink
Merge pull request #347 from YuhanLiin/histbuf-api-additions
Browse files Browse the repository at this point in the history
Add `recent_index`, `oldest_index`, `oldest,` and `is_filled` to HistoryBuffer API
  • Loading branch information
newAM authored Dec 20, 2023
2 parents fc099ec + 2cafa8c commit c0649c4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Added `format` macro.
- Added `String::from_utf16`.
- Added `is_full`, `recent_index`, `oldest`, and `oldest_index` to `HistoryBuffer`

### Changed

Expand Down
89 changes: 87 additions & 2 deletions src/histbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
N
}

/// Returns whether the buffer is full
#[inline]
pub fn is_full(&self) -> bool {
self.filled
}

/// Writes an element to the buffer, overwriting the oldest value.
pub fn write(&mut self, t: T) {
if self.filled {
Expand Down Expand Up @@ -182,14 +188,70 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
/// assert_eq!(x.recent(), Some(&10));
/// ```
pub fn recent(&self) -> Option<&T> {
self.recent_index()
.map(|i| unsafe { &*self.data[i].as_ptr() })
}

/// Returns index of the most recently written value in the underlying slice.
///
/// # Examples
///
/// ```
/// use heapless::HistoryBuffer;
///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new();
/// x.write(4);
/// x.write(10);
/// assert_eq!(x.recent_index(), Some(1));
/// ```
pub fn recent_index(&self) -> Option<usize> {
if self.write_at == 0 {
if self.filled {
Some(unsafe { &*self.data[self.capacity() - 1].as_ptr() })
Some(self.capacity() - 1)
} else {
None
}
} else {
Some(unsafe { &*self.data[self.write_at - 1].as_ptr() })
Some(self.write_at - 1)
}
}

/// Returns a reference to the oldest value in the buffer.
///
/// # Examples
///
/// ```
/// use heapless::HistoryBuffer;
///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new();
/// x.write(4);
/// x.write(10);
/// assert_eq!(x.oldest(), Some(&4));
/// ```
pub fn oldest(&self) -> Option<&T> {
self.oldest_index()
.map(|i| unsafe { &*self.data[i].as_ptr() })
}

/// Returns index of the oldest value in the underlying slice.
///
/// # Examples
///
/// ```
/// use heapless::HistoryBuffer;
///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new();
/// x.write(4);
/// x.write(10);
/// assert_eq!(x.oldest_index(), Some(0));
/// ```
pub fn oldest_index(&self) -> Option<usize> {
if self.filled {
Some(self.write_at)
} else if self.write_at == 0 {
None
} else {
Some(0)
}
}

Expand Down Expand Up @@ -381,9 +443,11 @@ mod tests {
assert_eq!(x.len(), 4);
assert_eq!(x.as_slice(), [1; 4]);
assert_eq!(*x, [1; 4]);
assert!(x.is_full());

let x: HistoryBuffer<u8, 4> = HistoryBuffer::new();
assert_eq!(x.as_slice(), []);
assert!(!x.is_full());
}

#[test]
Expand Down Expand Up @@ -457,18 +521,39 @@ mod tests {
#[test]
fn recent() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new();
assert_eq!(x.recent_index(), None);
assert_eq!(x.recent(), None);

x.write(1);
x.write(4);
assert_eq!(x.recent_index(), Some(1));
assert_eq!(x.recent(), Some(&4));

x.write(5);
x.write(6);
x.write(10);
assert_eq!(x.recent_index(), Some(0));
assert_eq!(x.recent(), Some(&10));
}

#[test]
fn oldest() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new();
assert_eq!(x.oldest_index(), None);
assert_eq!(x.oldest(), None);

x.write(1);
x.write(4);
assert_eq!(x.oldest_index(), Some(0));
assert_eq!(x.oldest(), Some(&1));

x.write(5);
x.write(6);
x.write(10);
assert_eq!(x.oldest_index(), Some(1));
assert_eq!(x.oldest(), Some(&4));
}

#[test]
fn as_slice() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new();
Expand Down

0 comments on commit c0649c4

Please sign in to comment.