From 465a7a7858a245182da8057a6b7f86a6c2b7cae1 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Tue, 26 May 2026 16:48:55 -0300 Subject: [PATCH 1/2] Add support for hybrid-array --- Cargo.toml | 13 +++-- src/array.rs | 3 + src/array/generic_array_impl.rs | 78 +++++++++++++++++++++++++- src/array/hybrid_array_impl.rs | 97 +++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 src/array/hybrid_array_impl.rs diff --git a/Cargo.toml b/Cargo.toml index e6a52d9..a326241 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,10 @@ serde_core = { version = "1.0", optional = true, default-features = false } arbitrary = { version = "1", optional = true } # Provides `BorshSerialize` and `BorshDeserialize implementations borsh = { version = "1.2.0", optional = true, default-features = false } -# Implements the trait `Array` for `GenericArray` struct. -generic-array = { version = "1.1.1", optional = true, default-features = false } +# Implements the trait `tinyvec::Array` for `GenericArray` struct. +generic-array = { version = "1.4.1", optional = true, default-features = false } +# Implements the trait `tinyvec::Array` for `hybrid_array::Array` struct. +hybrid-array = { version = "0.4.12", optional = true, default-features = false } # Provides derived `BitEncode` and `BitDecode` implementations bin-proto = { version = "0.12.5", optional = true, default-features = false } # Provides `Format` implementations @@ -30,13 +32,13 @@ defmt = { version = "1.0", optional = true } default = [] # Provide things that utilize the `alloc` crate, namely `TinyVec`. -alloc = ["tinyvec_macros"] +alloc = ["tinyvec_macros", "hybrid-array?/alloc", "generic-array?/alloc"] # Provide things that require Rust's `std` module std = ["alloc"] # Provides `Serialize` and `Deserialize` implementations -serde = ["dep:serde_core"] +serde = ["dep:serde_core", "hybrid-array?/serde", "generic-array?/serde"] # (not part of Vec!) Extra methods to let you grab the slice of memory after the # "active" portion of an `ArrayVec` or `SliceVec`. @@ -82,6 +84,9 @@ experimental_write_impl = [] # and thus a nightly compiler, but is only used in benchmarks. real_blackbox = ["criterion/real_blackbox"] +# enable third-part support +arbitrary = ["dep:arbitrary", "hybrid-array?/arbitrary", "generic-array?/arbitrary"] + [package.metadata.docs.rs] features = ["alloc", "std", "grab_spare_slice", "latest_stable_rust", "serde", "borsh", "defmt", "bin-proto"] rustdoc-args = ["--cfg","docs_rs"] diff --git a/src/array.rs b/src/array.rs index 78ef2f3..2aea662 100644 --- a/src/array.rs +++ b/src/array.rs @@ -42,3 +42,6 @@ mod const_generic_impl; #[cfg(feature = "generic-array")] mod generic_array_impl; + +#[cfg(feature = "hybrid-array")] +mod hybrid_array_impl; diff --git a/src/array/generic_array_impl.rs b/src/array/generic_array_impl.rs index b61bd60..02d1ca2 100644 --- a/src/array/generic_array_impl.rs +++ b/src/array/generic_array_impl.rs @@ -1,7 +1,7 @@ use core::default; use super::Array; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::{ArrayLength, GenericArray, IntoArrayLength}; impl Array for GenericArray { type Item = T; @@ -9,12 +9,12 @@ impl Array for GenericArray { #[inline(always)] fn as_slice(&self) -> &[T] { - &*self + GenericArray::as_slice(self) } #[inline(always)] fn as_slice_mut(&mut self) -> &mut [T] { - &mut *self + GenericArray::as_mut_slice(self) } #[inline(always)] @@ -22,3 +22,75 @@ impl Array for GenericArray { ::default() } } + +impl IntoArrayLength for crate::ArrayVec where T: IntoArrayLength { + type ArrayLength = ::ArrayLength; +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{ArrayVec, array_vec}; + use generic_array::ConstGenericArray; + type TinyGenericVec = ArrayVec>; + + #[test] + fn retain_mut_empty_vec() { + let mut av: TinyGenericVec = TinyGenericVec::::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_all_elements() { + let mut av: TinyGenericVec = array_vec!(ConstGenericArray => 2, 4, 6, 8); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 4); + assert_eq!(av.as_slice(), &[2, 4, 6, 8]); + } + + #[test] + fn retain_mut_some_elements() { + let mut av: TinyGenericVec = array_vec!(ConstGenericArray => 1, 2, 3, 4); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 2); + assert_eq!(av.as_slice(), &[2, 4]); + } + + #[test] + fn retain_mut_no_elements() { + let mut av: TinyGenericVec = array_vec!(ConstGenericArray => 1, 3, 5, 7); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_zero_capacity() { + let mut av: TinyGenericVec = ArrayVec::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[cfg(feature = "alloc")] + #[test] + fn array_like_debug() { + #[derive(Debug, Default, Copy, Clone)] + struct S { + x: u8, + y: u8, + } + + use core::fmt::Write; + use alloc::string::String; + + let mut ar: ConstGenericArray = ConstGenericArray::::from_array([S { x: 1, y: 2 }, S { x: 3, y: 4 }]); + let mut buf_ar = String::new(); + write!(&mut buf_ar, "{ar:#?}"); + + let av: TinyGenericVec = TinyGenericVec::::from_array_len(ar, 2); + let mut buf_av = String::new(); + write!(&mut buf_av, "{av:#?}"); + + assert_eq!(buf_av, buf_ar) + } +} diff --git a/src/array/hybrid_array_impl.rs b/src/array/hybrid_array_impl.rs new file mode 100644 index 0000000..6478a5a --- /dev/null +++ b/src/array/hybrid_array_impl.rs @@ -0,0 +1,97 @@ +use core::default; + +use super::Array; +use hybrid_array::{Array as HybridArray, AssocArraySize, ArraySize, typenum::Unsigned}; + +impl Array for HybridArray { + type Item = T; + const CAPACITY: usize = ::USIZE; + + #[inline(always)] + fn as_slice(&self) -> &[T] { + HybridArray::as_slice(self) + } + + #[inline(always)] + fn as_slice_mut(&mut self) -> &mut [T] { + HybridArray::as_mut_slice(self) + } + + #[inline(always)] + fn default() -> Self { + ::default() + } +} + +impl AssocArraySize for crate::ArrayVec where T: AssocArraySize { + type Size = ::Size; +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{ArrayVec, array_vec}; + use hybrid_array::ArrayN; + type TinyHybridVec = ArrayVec>; + + #[test] + fn retain_mut_empty_vec() { + let mut av: TinyHybridVec = TinyHybridVec::::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_all_elements() { + let mut av: TinyHybridVec = array_vec!(ArrayN => 2, 4, 6, 8); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 4); + assert_eq!(av.as_slice(), &[2, 4, 6, 8]); + } + + #[test] + fn retain_mut_some_elements() { + let mut av: TinyHybridVec = array_vec!(ArrayN => 1, 2, 3, 4); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 2); + assert_eq!(av.as_slice(), &[2, 4]); + } + + #[test] + fn retain_mut_no_elements() { + let mut av: TinyHybridVec = array_vec!(ArrayN => 1, 3, 5, 7); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[test] + fn retain_mut_zero_capacity() { + let mut av: TinyHybridVec = ArrayVec::new(); + av.retain_mut(|&mut x| x % 2 == 0); + assert_eq!(av.len(), 0); + } + + #[cfg(feature = "alloc")] + #[test] + fn array_like_debug() { + #[derive(Debug, Default, Copy, Clone)] + struct S { + x: u8, + y: u8, + } + + use core::fmt::Write; + use alloc::string::String; + use hybrid_array::{Array, sizes::U2}; + + let mut ar: Array = Array::([S { x: 1, y: 2 }, S { x: 3, y: 4 }]); + let mut buf_ar = String::new(); + write!(&mut buf_ar, "{ar:#?}"); + + let av: TinyHybridVec = TinyHybridVec::::from(ar); + let mut buf_av = String::new(); + write!(&mut buf_av, "{av:#?}"); + + assert_eq!(buf_av, buf_ar) + } +} From a36d4260cc484dbef0e7628abb8386ded6e7df17 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Tue, 26 May 2026 17:26:51 -0300 Subject: [PATCH 2/2] fix unit tests --- src/array/generic_array_impl.rs | 4 ++-- src/array/hybrid_array_impl.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/array/generic_array_impl.rs b/src/array/generic_array_impl.rs index 02d1ca2..f229af9 100644 --- a/src/array/generic_array_impl.rs +++ b/src/array/generic_array_impl.rs @@ -85,11 +85,11 @@ mod test { let mut ar: ConstGenericArray = ConstGenericArray::::from_array([S { x: 1, y: 2 }, S { x: 3, y: 4 }]); let mut buf_ar = String::new(); - write!(&mut buf_ar, "{ar:#?}"); + write!(&mut buf_ar, "{:#?}", ar.as_slice()).unwrap(); let av: TinyGenericVec = TinyGenericVec::::from_array_len(ar, 2); let mut buf_av = String::new(); - write!(&mut buf_av, "{av:#?}"); + write!(&mut buf_av, "{av:#?}").unwrap(); assert_eq!(buf_av, buf_ar) } diff --git a/src/array/hybrid_array_impl.rs b/src/array/hybrid_array_impl.rs index 6478a5a..7dc9a72 100644 --- a/src/array/hybrid_array_impl.rs +++ b/src/array/hybrid_array_impl.rs @@ -86,12 +86,11 @@ mod test { let mut ar: Array = Array::([S { x: 1, y: 2 }, S { x: 3, y: 4 }]); let mut buf_ar = String::new(); - write!(&mut buf_ar, "{ar:#?}"); + write!(&mut buf_ar, "{:#?}", ar.as_slice()).unwrap(); let av: TinyHybridVec = TinyHybridVec::::from(ar); let mut buf_av = String::new(); - write!(&mut buf_av, "{av:#?}"); - + write!(&mut buf_av, "{av:#?}").unwrap(); assert_eq!(buf_av, buf_ar) } }