From f3b24a7f76297ff548c779b3f7eb74faea59e36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Wagenh=C3=A4user?= Date: Tue, 25 Mar 2025 14:48:54 +0100 Subject: [PATCH] Make the heapless to alloc Vec conversion fallible as well. This allows to catch OOM errors. --- CHANGELOG.md | 4 ++-- src/vec/mod.rs | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4df7eeb..c29d8608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,8 +42,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Make `String::from_utf8_unchecked` const. - Implemented `PartialEq` and `Eq` for `Deque`. - Added `alloc` feature to enable `alloc`-Vec interoperability. -- Added `From` impl for `Vec`. -- Added `From` impl for `alloc::vec::Vec`. +- Added `TryFrom` impl for `Vec`. +- Added `TryFrom` impl for `alloc::vec::Vec`. ### Changed diff --git a/src/vec/mod.rs b/src/vec/mod.rs index fd3c85be..40ddf98a 100644 --- a/src/vec/mod.rs +++ b/src/vec/mod.rs @@ -1232,6 +1232,7 @@ impl TryFrom> for Vec { let mut vec = Vec::new(); for e in alloc_vec { + // Push each element individually to allow handling capacity errors. vec.push(e).map_err(|_| ())?; } @@ -1241,10 +1242,26 @@ impl TryFrom> for Vec { #[cfg(feature = "alloc")] /// Converts the given `Vec` into an `alloc::vec::Vec`. -impl From> for alloc::vec::Vec { +impl TryFrom> for alloc::vec::Vec { + type Error = (); + /// Converts the given `Vec` into an `alloc::vec::Vec`. - fn from(vec: Vec) -> Self { - alloc::vec::Vec::from_iter(vec.into_iter()) + /// + /// # Errors + /// + /// Returns `Err` if the `alloc::vec::Vec` fails to allocate memory. + fn try_from(vec: Vec) -> Result { + 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(vec.len()).map_err(|_| ())?; + + // Transfer the elements, since we reserved enough space above, this + // should not fail due to OOM. + alloc_vec.extend(vec); + + Ok(alloc_vec) } }