diff options
author | Wedson Almeida Filho <walmeida@microsoft.com> | 2024-03-27 22:35:55 -0300 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2024-04-16 22:03:14 +0200 |
commit | 03989773a94490383b062912feb0c4d175f20845 (patch) | |
tree | 14df87b69f4c7820ebe8802761496594feae13f0 /rust/kernel/alloc | |
parent | 31d94d8f586df55e7dce47a67a8428f46d09f906 (diff) |
rust: alloc: introduce the `VecExt` trait
Make `try_with_capacity`, `try_push`, and `try_extend_from_slice`
methods available in `Vec` even though it doesn't implement them. It is
implemented with `try_reserve` and `push_within_capacity`.
This is in preparation for switching to the upstream `alloc` crate.
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Suggested-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-3-wedsonaf@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/alloc')
-rw-r--r-- | rust/kernel/alloc/vec_ext.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/rust/kernel/alloc/vec_ext.rs b/rust/kernel/alloc/vec_ext.rs new file mode 100644 index 000000000000..311e62cc5784 --- /dev/null +++ b/rust/kernel/alloc/vec_ext.rs @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Extensions to [`Vec`] for fallible allocations. + +use alloc::{collections::TryReserveError, vec::Vec}; +use core::result::Result; + +/// Extensions to [`Vec`]. +pub trait VecExt<T>: Sized { + /// Creates a new [`Vec`] instance with at least the given capacity. + fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>; + + /// Appends an element to the back of the [`Vec`] instance. + fn try_push(&mut self, v: T) -> Result<(), TryReserveError>; + + /// Pushes clones of the elements of slice into the [`Vec`] instance. + fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError> + where + T: Clone; +} + +impl<T> VecExt<T> for Vec<T> { + fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError> { + let mut v = Vec::new(); + v.try_reserve(capacity)?; + Ok(v) + } + + fn try_push(&mut self, v: T) -> Result<(), TryReserveError> { + if let Err(retry) = self.push_within_capacity(v) { + self.try_reserve(1)?; + let _ = self.push_within_capacity(retry); + } + Ok(()) + } + + fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError> + where + T: Clone, + { + self.try_reserve(other.len())?; + for item in other { + self.try_push(item.clone())?; + } + + Ok(()) + } +} |