Merge branch 'main' into cstring

This commit is contained in:
Yota Toyama 2025-04-09 13:45:09 +09:00 committed by GitHub
commit ce6d252f7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 84 additions and 2 deletions

View File

@ -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:

View File

@ -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`.

View File

@ -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"]

View File

@ -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;

View File

@ -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
}