From f2cc6a6b2ecca8eb17a37b7a77b7aaeff8a89abc Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 4 Mar 2024 20:49:13 -0700 Subject: [PATCH 1/2] Add ZeroVec::take_first --- utils/zerovec/src/zerovec/mod.rs | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index a0d0f83be36..2627efd1494 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -914,6 +914,41 @@ where *self = Self::new_borrowed(&[]) } + /// Removes the first element of the ZeroVec. The ZeroVec remains in the same + /// borrowed or owned state. + /// + /// # Examples + /// + /// ``` + /// # use crate::zerovec::ule::AsULE; + /// use zerovec::ZeroVec; + /// + /// let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; + /// let mut zerovec: ZeroVec = + /// ZeroVec::parse_byte_slice(bytes).expect("infallible"); + /// assert!(!zerovec.is_owned()); + /// + /// let first = zerovec.take_first().unwrap(); + /// assert_eq!(first, 0x00D3); + /// assert!(!zerovec.is_owned()); + /// ``` + pub fn take_first(&mut self) -> Option { + match core::mem::take(self).into_cow() { + Cow::Owned(mut vec) => { + let ule = vec.remove(0); + let rv = T::from_unaligned(ule); + *self = ZeroVec::new_owned(vec); + Some(rv) + } + Cow::Borrowed(b) => { + let (ule, remainder) = b.split_first()?; + let rv = T::from_unaligned(*ule); + *self = ZeroVec::new_borrowed(remainder); + Some(rv) + } + } + } + /// Converts the type into a `Cow<'a, [T::ULE]>`, which is /// the logical equivalent of this type's internal representation #[inline] From 63dbf0e9355c402e108bbe24238ebb06d4692c7e Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Mon, 4 Mar 2024 20:53:14 -0700 Subject: [PATCH 2/2] Add ZeroVec::take_last --- utils/zerovec/src/zerovec/mod.rs | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 2627efd1494..50cbb3dd527 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -931,10 +931,19 @@ where /// let first = zerovec.take_first().unwrap(); /// assert_eq!(first, 0x00D3); /// assert!(!zerovec.is_owned()); + /// + /// let mut zerovec = zerovec.into_owned(); + /// assert!(zerovec.is_owned()); + /// let first = zerovec.take_first().unwrap(); + /// assert_eq!(first, 0x0119); + /// assert!(zerovec.is_owned()); /// ``` pub fn take_first(&mut self) -> Option { match core::mem::take(self).into_cow() { Cow::Owned(mut vec) => { + if vec.is_empty() { + return None; + } let ule = vec.remove(0); let rv = T::from_unaligned(ule); *self = ZeroVec::new_owned(vec); @@ -949,6 +958,47 @@ where } } + /// Removes the last element of the ZeroVec. The ZeroVec remains in the same + /// borrowed or owned state. + /// + /// # Examples + /// + /// ``` + /// # use crate::zerovec::ule::AsULE; + /// use zerovec::ZeroVec; + /// + /// let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; + /// let mut zerovec: ZeroVec = + /// ZeroVec::parse_byte_slice(bytes).expect("infallible"); + /// assert!(!zerovec.is_owned()); + /// + /// let last = zerovec.take_last().unwrap(); + /// assert_eq!(last, 0x01CD); + /// assert!(!zerovec.is_owned()); + /// + /// let mut zerovec = zerovec.into_owned(); + /// assert!(zerovec.is_owned()); + /// let last = zerovec.take_last().unwrap(); + /// assert_eq!(last, 0x01A5); + /// assert!(zerovec.is_owned()); + /// ``` + pub fn take_last(&mut self) -> Option { + match core::mem::take(self).into_cow() { + Cow::Owned(mut vec) => { + let ule = vec.pop()?; + let rv = T::from_unaligned(ule); + *self = ZeroVec::new_owned(vec); + Some(rv) + } + Cow::Borrowed(b) => { + let (ule, remainder) = b.split_last()?; + let rv = T::from_unaligned(*ule); + *self = ZeroVec::new_borrowed(remainder); + Some(rv) + } + } + } + /// Converts the type into a `Cow<'a, [T::ULE]>`, which is /// the logical equivalent of this type's internal representation #[inline]