mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-28 13:00:26 +00:00
Merge pull request #340 from xgroleau/feat/add-bytes-support
Add support for `Bytes`
This commit is contained in:
commit
b6c073923d
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### Added
|
||||
|
||||
- Added `bytes::Buf` and `bytes::BufMut` implementations for `Vec`.
|
||||
- Added `format` macro.
|
||||
- Added `String::from_utf16`.
|
||||
- Added `is_full`, `recent_index`, `oldest`, and `oldest_index` to `HistoryBuffer`
|
||||
|
@ -15,6 +15,8 @@ repository = "https://github.com/rust-embedded/heapless"
|
||||
version = "0.8.0"
|
||||
|
||||
[features]
|
||||
bytes = ["dep:bytes"]
|
||||
|
||||
# Enable polyfilling of atomics via `portable-atomic`.
|
||||
# `portable-atomic` polyfills some functionality by default, but to get full atomics you must
|
||||
# enable one of its features to tell it how to do it. See `portable-atomic` documentation for details.
|
||||
@ -42,6 +44,7 @@ mpmc_large = []
|
||||
nightly = []
|
||||
|
||||
[dependencies]
|
||||
bytes = { version = "1", default-features = false, optional = true }
|
||||
portable-atomic = { version = "1.0", optional = true }
|
||||
hash32 = "0.3.0"
|
||||
serde = { version = "1", optional = true, default-features = false }
|
||||
@ -58,6 +61,7 @@ static_assertions = "1.1.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [
|
||||
"bytes",
|
||||
"ufmt",
|
||||
"serde",
|
||||
"defmt",
|
||||
|
107
src/bytes.rs
Normal file
107
src/bytes.rs
Normal file
@ -0,0 +1,107 @@
|
||||
//! Bytes implementations for heapless types
|
||||
|
||||
use crate::Vec;
|
||||
use bytes::{buf::UninitSlice, Buf, BufMut};
|
||||
|
||||
unsafe impl<const N: usize> Buf for Vec<u8, N> {
|
||||
#[inline]
|
||||
fn remaining(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn chunk(&mut self) -> &[u8] {
|
||||
self.as_slice()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn advance(&mut self, cnt: usize) {
|
||||
assert!(
|
||||
cnt <= self.remaining(),
|
||||
"cannot advance past `remaining`: {:?} <= {:?}",
|
||||
cnt,
|
||||
self.remaining(),
|
||||
);
|
||||
unsafe {
|
||||
// SAFETY: We've checked that `cnt` <= `self.remaining()` and we know that
|
||||
// `self.remaining()` <= `self.cap`.
|
||||
self.advance_unchecked(cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<const N: usize> BufMut for Vec<u8, N> {
|
||||
#[inline]
|
||||
fn remaining_mut(&self) -> usize {
|
||||
N - self.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||
let len = self.len();
|
||||
let pos = len + cnt;
|
||||
if pos >= N {
|
||||
panic!("Advance out of range");
|
||||
}
|
||||
self.set_len(pos);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn chunk_mut(&mut self) -> &mut UninitSlice {
|
||||
let len = self.len();
|
||||
let ptr = self.as_mut_ptr();
|
||||
unsafe { &mut UninitSlice::from_raw_parts_mut(ptr, N)[len..] }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Vec;
|
||||
use bytes::BufMut;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn buf_advance_out_of_bounds() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
vec.advance(9)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buf_remaining() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
assert_eq!(vec.remaining(), 8);
|
||||
vec.push(42).unwrap();
|
||||
assert_eq!(vec.remaining(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buf_chunk() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
assert_eq!(vec.chunk().len(), 8);
|
||||
unsafe { vec.advance_mut(1) };
|
||||
assert_eq!(vec.chunk().len(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn buf_mut_advance_mut_out_of_bounds() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
unsafe { vec.advance_mut(9) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buf_mut_remaining_mut() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
assert_eq!(vec.remaining_mut(), 8);
|
||||
vec.push(42).unwrap();
|
||||
assert_eq!(vec.remaining_mut(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buf_mut_chunk_mut() {
|
||||
let mut vec: Vec<u8, 8> = Vec::new();
|
||||
assert_eq!(vec.chunk_mut().len(), 8);
|
||||
unsafe { vec.advance_mut(1) };
|
||||
assert_eq!(vec.chunk_mut().len(), 7);
|
||||
}
|
||||
}
|
@ -192,6 +192,8 @@ mod de;
|
||||
mod ser;
|
||||
|
||||
pub mod binary_heap;
|
||||
#[cfg(feature = "bytes")]
|
||||
mod bytes;
|
||||
#[cfg(feature = "defmt")]
|
||||
mod defmt;
|
||||
#[cfg(any(
|
||||
|
Loading…
x
Reference in New Issue
Block a user