mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 06:50:32 +00:00
Merge branch 'main' into cstring
This commit is contained in:
commit
ce6d252f7f
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -165,7 +165,7 @@ jobs:
|
||||
run: |
|
||||
cargo check --target=${{ matrix.target }}
|
||||
cargo check --target=${{ matrix.target }} --features="portable-atomic-critical-section"
|
||||
cargo check --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large"
|
||||
cargo check --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large alloc"
|
||||
|
||||
doc:
|
||||
name: doc
|
||||
@ -208,7 +208,7 @@ jobs:
|
||||
|
||||
- name: cargo rustdoc
|
||||
env: {"RUSTDOCFLAGS": "-D warnings --cfg docsrs"}
|
||||
run: cargo rustdoc --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large portable-atomic-critical-section"
|
||||
run: cargo rustdoc --target=${{ matrix.target }} --features="ufmt serde defmt mpmc_large portable-atomic-critical-section alloc"
|
||||
|
||||
# Run cpass tests
|
||||
testcpass:
|
||||
|
@ -42,6 +42,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`.
|
||||
- Make `String::from_utf8_unchecked` const.
|
||||
- Implemented `PartialEq` and `Eq` for `Deque`.
|
||||
- Added `alloc` feature to enable `alloc`-Vec interoperability.
|
||||
- Added `TryFrom<alloc::vec::Vec>` impl for `Vec`.
|
||||
- Added `TryFrom<Vec>` impl for `alloc::vec::Vec`.
|
||||
- Added `truncate` to `IndexMap`.
|
||||
- Added `get_index` and `get_index_mut` to `IndexMap`.
|
||||
- Added `String::uDisplay`.
|
||||
|
@ -41,6 +41,9 @@ defmt = ["dep:defmt"]
|
||||
# Enable larger MPMC sizes.
|
||||
mpmc_large = []
|
||||
|
||||
# Implement some alloc Vec interoperability
|
||||
alloc = []
|
||||
|
||||
nightly = []
|
||||
|
||||
[dependencies]
|
||||
@ -67,6 +70,7 @@ features = [
|
||||
"defmt",
|
||||
"mpmc_large",
|
||||
"portable-atomic-critical-section",
|
||||
"alloc",
|
||||
]
|
||||
# for the pool module
|
||||
targets = ["i686-unknown-linux-gnu"]
|
||||
|
@ -153,6 +153,9 @@
|
||||
clippy::if_not_else
|
||||
)]
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
|
||||
pub use binary_heap::BinaryHeap;
|
||||
pub use c_string::CString;
|
||||
pub use deque::Deque;
|
||||
|
@ -1277,6 +1277,53 @@ impl<T, S: VecStorage<T> + ?Sized> Drop for VecInner<T, S> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Converts the given `alloc::vec::Vec<T>` into a `Vec<T, N>`.
|
||||
impl<T, const N: usize> TryFrom<alloc::vec::Vec<T>> for Vec<T, N> {
|
||||
type Error = CapacityError;
|
||||
|
||||
/// Converts the given `alloc::vec::Vec<T>` into a `Vec<T, N>`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns `Err` if the length of the `alloc::vec::Vec<T>` is greater than `N`.
|
||||
fn try_from(alloc_vec: alloc::vec::Vec<T>) -> Result<Self, Self::Error> {
|
||||
let mut vec = Vec::new();
|
||||
|
||||
for e in alloc_vec {
|
||||
// Push each element individually to allow handling capacity errors.
|
||||
vec.push(e).map_err(|_| CapacityError {})?;
|
||||
}
|
||||
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
/// Converts the given `Vec<T, N>` into an `alloc::vec::Vec<T>`.
|
||||
impl<T, const N: usize> TryFrom<Vec<T, N>> for alloc::vec::Vec<T> {
|
||||
type Error = alloc::collections::TryReserveError;
|
||||
|
||||
/// Converts the given `Vec<T, N>` into an `alloc::vec::Vec<T>`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns `Err` if the `alloc::vec::Vec` fails to allocate memory.
|
||||
fn try_from(vec: Vec<T, N>) -> Result<Self, Self::Error> {
|
||||
let mut alloc_vec = alloc::vec::Vec::new();
|
||||
|
||||
// Allocate enough space for the elements, return an error if the
|
||||
// allocation fails.
|
||||
alloc_vec.try_reserve_exact(vec.len())?;
|
||||
|
||||
// Transfer the elements, since we reserved enough space above, this
|
||||
// should not fail due to OOM.
|
||||
alloc_vec.extend(vec);
|
||||
|
||||
Ok(alloc_vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec<T, N> {
|
||||
type Error = CapacityError;
|
||||
|
||||
@ -2099,6 +2146,31 @@ mod tests {
|
||||
assert!(v.spare_capacity_mut().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn heapless_to_alloc() {
|
||||
let mut hv: Vec<u8, 4> = Vec::new();
|
||||
hv.push(0).unwrap();
|
||||
hv.push(1).unwrap();
|
||||
|
||||
let av: alloc::vec::Vec<u8> = hv.clone().try_into().unwrap();
|
||||
assert_eq!(av.as_slice(), hv.as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn alloc_to_heapless() {
|
||||
let mut av: alloc::vec::Vec<u8> = alloc::vec::Vec::new();
|
||||
av.push(0);
|
||||
av.push(1);
|
||||
|
||||
let hv: Vec<u8, 2> = av.clone().try_into().unwrap();
|
||||
assert_eq!(hv.as_slice(), av.as_slice());
|
||||
|
||||
let _: crate::CapacityError =
|
||||
<alloc::vec::Vec<u8> as TryInto<Vec<u8, 1>>>::try_into(av.clone()).unwrap_err();
|
||||
}
|
||||
|
||||
fn _test_variance<'a: 'b, 'b>(x: Vec<&'a (), 42>) -> Vec<&'b (), 42> {
|
||||
x
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user