mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +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
|
||||||
|
|
||||||
|
- Added `bytes::Buf` and `bytes::BufMut` implementations for `Vec`.
|
||||||
- Added `format` macro.
|
- Added `format` macro.
|
||||||
- Added `String::from_utf16`.
|
- Added `String::from_utf16`.
|
||||||
- Added `is_full`, `recent_index`, `oldest`, and `oldest_index` to `HistoryBuffer`
|
- 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"
|
version = "0.8.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
bytes = ["dep:bytes"]
|
||||||
|
|
||||||
# Enable polyfilling of atomics via `portable-atomic`.
|
# Enable polyfilling of atomics via `portable-atomic`.
|
||||||
# `portable-atomic` polyfills some functionality by default, but to get full atomics you must
|
# `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.
|
# 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 = []
|
nightly = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bytes = { version = "1", default-features = false, optional = true }
|
||||||
portable-atomic = { version = "1.0", optional = true }
|
portable-atomic = { version = "1.0", optional = true }
|
||||||
hash32 = "0.3.0"
|
hash32 = "0.3.0"
|
||||||
serde = { version = "1", optional = true, default-features = false }
|
serde = { version = "1", optional = true, default-features = false }
|
||||||
@ -58,6 +61,7 @@ static_assertions = "1.1.0"
|
|||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = [
|
features = [
|
||||||
|
"bytes",
|
||||||
"ufmt",
|
"ufmt",
|
||||||
"serde",
|
"serde",
|
||||||
"defmt",
|
"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;
|
mod ser;
|
||||||
|
|
||||||
pub mod binary_heap;
|
pub mod binary_heap;
|
||||||
|
#[cfg(feature = "bytes")]
|
||||||
|
mod bytes;
|
||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
mod defmt;
|
mod defmt;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user