Skip to content

Commit bee84f9

Browse files
committed
Merge branch 'main' into impl-alloc-interop
2 parents 4251a17 + b6c0739 commit bee84f9

28 files changed

+1305
-584
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ jobs:
165165
run: |
166166
cargo check --target=${{ matrix.target }}
167167
cargo check --target=${{ matrix.target }} --features="portable-atomic-critical-section"
168-
cargo check --target=${{ matrix.target }} --features="ufmt serde defmt-03 mpmc_large alloc"
168+
cargo check --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large alloc"
169169
170170
doc:
171171
name: doc
@@ -208,7 +208,7 @@ jobs:
208208

209209
- name: cargo rustdoc
210210
env: {"RUSTDOCFLAGS": "-D warnings --cfg docsrs"}
211-
run: cargo rustdoc --target=${{ matrix.target }} --features="ufmt serde defmt-03 mpmc_large portable-atomic-critical-section alloc"
211+
run: cargo rustdoc --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large portable-atomic-critical-section alloc"
212212

213213
# Run cpass tests
214214
testcpass:

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Added
1111

12+
- Added `bytes::Buf` and `bytes::BufMut` implementations for `Vec`.
1213
- Added `format` macro.
1314
- Added `String::from_utf16`.
1415
- Added `is_full`, `recent_index`, `oldest`, and `oldest_index` to `HistoryBuffer`
@@ -44,10 +45,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
4445
- Added `alloc` feature to enable `alloc`-Vec interoperability.
4546
- Added `TryFrom<alloc::vec::Vec>` impl for `Vec`.
4647
- Added `TryFrom<Vec>` impl for `alloc::vec::Vec`.
48+
- Added `truncate` to `IndexMap`.
49+
- Added `get_index` and `get_index_mut` to `IndexMap`.
50+
- Added `String::uDisplay`.
4751

4852
### Changed
4953

54+
- Updated defmt from 0.3 to 1.0.1
55+
- Changed the feature name from `defmt-03` to `defmt`.
56+
- Changed the error type of these methods from `()` to `CapacityError`.
57+
- `String::push_str`
58+
- `String::push`
59+
- `Vec::extend_from_slice`
60+
- `Vec::from_slice`
61+
- `Vec::resize_default`
62+
- `Vec::resize`
63+
- Renamed `FromUtf16Error::DecodeUtf16Error` to `FromUtf16Error::DecodeUtf16`.
5064
- Changed `stable_deref_trait` to a platform-dependent dependency.
65+
- Changed `SortedLinkedList::pop` return type from `Result<T, ()>` to `Option<T>` to match `std::vec::pop`.
66+
- `Vec::capacity` is no longer a `const` function.
67+
- Relaxed bounds on `PartialEq` for `IndexMap` from `V: Eq` to `V1: PartialEq<V2>`.
68+
- Relaxed bounds on `PartialEq` for `LinearMap` from `V: PartialEq` to `V1: PartialEq<V2>`.
5169

5270
### Fixed
5371

@@ -58,6 +76,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5876
- Fixed `MpMcQueue` with `mpmc_large` feature.
5977
- Fix missing `Drop` for `MpMcQueue`
6078

79+
### Removed
80+
81+
- `Vec::storage_capacity` has been removed and `Vec::capacity` must be used instead.
82+
6183
## [v0.8.0] - 2023-11-07
6284

6385
### Added
@@ -93,6 +115,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
93115
- `ufmt-impl` is now `ufmt`
94116
- `cas` is removed, atomic polyfilling is now opt-in via the `portable-atomic` feature.
95117
- `Vec::as_mut_slice` is now a public method.
118+
- `ufmt` functions are annotated with `inline`.
96119

97120
### Fixed
98121

Cargo.toml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ repository = "https://github.com/rust-embedded/heapless"
1515
version = "0.8.0"
1616

1717
[features]
18+
bytes = ["dep:bytes"]
19+
1820
# Enable polyfilling of atomics via `portable-atomic`.
1921
# `portable-atomic` polyfills some functionality by default, but to get full atomics you must
2022
# enable one of its features to tell it how to do it. See `portable-atomic` documentation for details.
@@ -31,10 +33,10 @@ portable-atomic-unsafe-assume-single-core = ["dep:portable-atomic", "portable-at
3133
serde = ["dep:serde"]
3234

3335
# implement ufmt traits.
34-
ufmt = ["dep:ufmt-write"]
36+
ufmt = ["dep:ufmt", "dep:ufmt-write"]
3537

36-
# Implement defmt::Format from defmt v0.3
37-
defmt-03 = ["dep:defmt"]
38+
# Implement `defmt::Format`.
39+
defmt = ["dep:defmt"]
3840

3941
# Enable larger MPMC sizes.
4042
mpmc_large = []
@@ -45,22 +47,31 @@ alloc = []
4547
nightly = []
4648

4749
[dependencies]
50+
bytes = { version = "1", default-features = false, optional = true }
4851
portable-atomic = { version = "1.0", optional = true }
4952
hash32 = "0.3.0"
5053
serde = { version = "1", optional = true, default-features = false }
54+
ufmt = { version = "0.2", optional = true }
5155
ufmt-write = { version = "0.1", optional = true }
52-
defmt = { version = ">=0.2.0,<0.4", optional = true }
56+
defmt = { version = "1.0.1", optional = true }
5357

5458
# for the pool module
5559
[target.'cfg(any(target_arch = "arm", target_pointer_width = "32", target_pointer_width = "64"))'.dependencies]
5660
stable_deref_trait = { version = "1", default-features = false }
5761

5862
[dev-dependencies]
59-
ufmt = "0.2"
6063
static_assertions = "1.1.0"
6164

6265
[package.metadata.docs.rs]
63-
features = ["ufmt", "serde", "defmt-03", "mpmc_large", "portable-atomic-critical-section", "alloc"]
66+
features = [
67+
"bytes",
68+
"ufmt",
69+
"serde",
70+
"defmt",
71+
"mpmc_large",
72+
"portable-atomic-critical-section",
73+
"alloc",
74+
]
6475
# for the pool module
6576
targets = ["i686-unknown-linux-gnu"]
6677
rustdoc-args = ["--cfg", "docsrs"]

src/binary_heap.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub type BinaryHeapView<T, K> = BinaryHeapInner<T, K, ViewVecStorage<T>>;
159159

160160
impl<T, K, const N: usize> BinaryHeap<T, K, N> {
161161
/* Constructors */
162-
/// Creates an empty BinaryHeap as a $K-heap.
162+
/// Creates an empty `BinaryHeap` as a $K-heap.
163163
///
164164
/// ```
165165
/// use heapless::binary_heap::{BinaryHeap, Max};
@@ -184,14 +184,16 @@ impl<T, K, const N: usize> BinaryHeap<T, K, N> {
184184
pub fn into_vec(self) -> Vec<T, N> {
185185
self.data
186186
}
187+
}
187188

189+
impl<T, K, S: VecStorage<T>> BinaryHeapInner<T, K, S> {
188190
/// Get a reference to the `BinaryHeap`, erasing the `N` const-generic.
189191
pub fn as_view(&self) -> &BinaryHeapView<T, K> {
190-
self
192+
S::as_binary_heap_view(self)
191193
}
192194
/// Get a mutable reference to the `BinaryHeap`, erasing the `N` const-generic.
193195
pub fn as_mut_view(&mut self) -> &mut BinaryHeapView<T, K> {
194-
self
196+
S::as_binary_heap_mut_view(self)
195197
}
196198
}
197199

@@ -203,7 +205,7 @@ where
203205
/* Public API */
204206
/// Returns the capacity of the binary heap.
205207
pub fn capacity(&self) -> usize {
206-
self.data.storage_capacity()
208+
self.data.capacity()
207209
}
208210

209211
/// Drops all items from the binary heap.
@@ -222,7 +224,7 @@ where
222224
/// assert!(heap.is_empty());
223225
/// ```
224226
pub fn clear(&mut self) {
225-
self.data.clear()
227+
self.data.clear();
226228
}
227229

228230
/// Returns the length of the binary heap.
@@ -386,7 +388,24 @@ where
386388

387389
/// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and
388390
/// returns it, without checking if the binary heap is empty.
389-
#[allow(clippy::missing_safety_doc)] // TODO
391+
///
392+
/// # Safety
393+
///
394+
/// The binary heap must not be empty.
395+
///
396+
/// # Example
397+
///
398+
/// ```
399+
/// use heapless::binary_heap::{BinaryHeap, Max};
400+
///
401+
/// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
402+
/// heap.push(42)?;
403+
///
404+
/// // SAFETY: We just pushed a number onto the heap, so it cannot be empty.
405+
/// let val = unsafe { heap.pop_unchecked() };
406+
/// assert_eq!(val, 42);
407+
/// # Ok::<(), u8>(())
408+
/// ```
390409
pub unsafe fn pop_unchecked(&mut self) -> T {
391410
let mut item = self.data.pop_unchecked();
392411

@@ -420,7 +439,23 @@ where
420439
}
421440

422441
/// Pushes an item onto the binary heap without first checking if it's full.
423-
#[allow(clippy::missing_safety_doc)] // TODO
442+
///
443+
/// # Safety
444+
///
445+
/// The binary heap must not be full.
446+
///
447+
/// # Example
448+
///
449+
/// ```
450+
/// use heapless::binary_heap::{BinaryHeap, Max};
451+
///
452+
/// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
453+
///
454+
/// // SAFETY: We just created an empty heap of size 8, so it cannot be full.
455+
/// unsafe { heap.push_unchecked(42) };
456+
/// assert_eq!(heap.len(), 1);
457+
/// assert_eq!(heap.peek(), Some(&42));
458+
/// ```
424459
pub unsafe fn push_unchecked(&mut self, item: T) {
425460
let old_len = self.len();
426461
self.data.push_unchecked(item);
@@ -596,14 +631,14 @@ where
596631
}
597632
}
598633

599-
impl<'a, T, K, S> PeekMutInner<'a, T, K, S>
634+
impl<T, K, S> PeekMutInner<'_, T, K, S>
600635
where
601636
T: Ord,
602637
K: Kind,
603638
S: VecStorage<T> + ?Sized,
604639
{
605640
/// Removes the peeked value from the heap and returns it.
606-
pub fn pop(mut this: PeekMutInner<'a, T, K, S>) -> T {
641+
pub fn pop(mut this: Self) -> T {
607642
let value = this.heap.pop().unwrap();
608643
this.sift = false;
609644
value

src/bytes.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//! Bytes implementations for heapless types
2+
3+
use crate::Vec;
4+
use bytes::{buf::UninitSlice, Buf, BufMut};
5+
6+
unsafe impl<const N: usize> Buf for Vec<u8, N> {
7+
#[inline]
8+
fn remaining(&self) -> usize {
9+
self.len()
10+
}
11+
12+
#[inline]
13+
fn chunk(&mut self) -> &[u8] {
14+
self.as_slice()
15+
}
16+
17+
#[inline]
18+
unsafe fn advance(&mut self, cnt: usize) {
19+
assert!(
20+
cnt <= self.remaining(),
21+
"cannot advance past `remaining`: {:?} <= {:?}",
22+
cnt,
23+
self.remaining(),
24+
);
25+
unsafe {
26+
// SAFETY: We've checked that `cnt` <= `self.remaining()` and we know that
27+
// `self.remaining()` <= `self.cap`.
28+
self.advance_unchecked(cnt);
29+
}
30+
}
31+
}
32+
33+
unsafe impl<const N: usize> BufMut for Vec<u8, N> {
34+
#[inline]
35+
fn remaining_mut(&self) -> usize {
36+
N - self.len()
37+
}
38+
39+
#[inline]
40+
unsafe fn advance_mut(&mut self, cnt: usize) {
41+
let len = self.len();
42+
let pos = len + cnt;
43+
if pos >= N {
44+
panic!("Advance out of range");
45+
}
46+
self.set_len(pos);
47+
}
48+
49+
#[inline]
50+
fn chunk_mut(&mut self) -> &mut UninitSlice {
51+
let len = self.len();
52+
let ptr = self.as_mut_ptr();
53+
unsafe { &mut UninitSlice::from_raw_parts_mut(ptr, N)[len..] }
54+
}
55+
}
56+
57+
#[cfg(test)]
58+
mod tests {
59+
use crate::Vec;
60+
use bytes::BufMut;
61+
62+
#[test]
63+
#[should_panic]
64+
fn buf_advance_out_of_bounds() {
65+
let mut vec: Vec<u8, 8> = Vec::new();
66+
vec.advance(9)
67+
}
68+
69+
#[test]
70+
fn buf_remaining() {
71+
let mut vec: Vec<u8, 8> = Vec::new();
72+
assert_eq!(vec.remaining(), 8);
73+
vec.push(42).unwrap();
74+
assert_eq!(vec.remaining(), 7);
75+
}
76+
77+
#[test]
78+
fn buf_chunk() {
79+
let mut vec: Vec<u8, 8> = Vec::new();
80+
assert_eq!(vec.chunk().len(), 8);
81+
unsafe { vec.advance_mut(1) };
82+
assert_eq!(vec.chunk().len(), 7);
83+
}
84+
85+
#[test]
86+
#[should_panic]
87+
fn buf_mut_advance_mut_out_of_bounds() {
88+
let mut vec: Vec<u8, 8> = Vec::new();
89+
unsafe { vec.advance_mut(9) };
90+
}
91+
92+
#[test]
93+
fn buf_mut_remaining_mut() {
94+
let mut vec: Vec<u8, 8> = Vec::new();
95+
assert_eq!(vec.remaining_mut(), 8);
96+
vec.push(42).unwrap();
97+
assert_eq!(vec.remaining_mut(), 7);
98+
}
99+
100+
#[test]
101+
fn buf_mut_chunk_mut() {
102+
let mut vec: Vec<u8, 8> = Vec::new();
103+
assert_eq!(vec.chunk_mut().len(), 8);
104+
unsafe { vec.advance_mut(1) };
105+
assert_eq!(vec.chunk_mut().len(), 7);
106+
}
107+
}

src/defmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Defmt implementations for heapless types
22
33
use crate::{
4-
string::StringInner,
4+
string::{StringInner, StringStorage},
55
vec::{VecInner, VecStorage},
66
};
77
use defmt::Formatter;
@@ -15,7 +15,7 @@ where
1515
}
1616
}
1717

18-
impl<S: VecStorage<u8> + ?Sized> defmt::Format for StringInner<S>
18+
impl<S: StringStorage + ?Sized> defmt::Format for StringInner<S>
1919
where
2020
u8: defmt::Format,
2121
{

0 commit comments

Comments
 (0)