From 10ed7786725b4266fbb207366d4fd9ab627abf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 30 Apr 2025 10:28:11 +0200 Subject: [PATCH] Make everything generic over LenType --- src/bytes_traits.rs | 3 +- src/lib.rs | 151 +++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 72 deletions(-) diff --git a/src/bytes_traits.rs b/src/bytes_traits.rs index ec193af..82d84ae 100644 --- a/src/bytes_traits.rs +++ b/src/bytes_traits.rs @@ -1,7 +1,8 @@ use crate::storage::BytesStorage; use bytes::{buf::UninitSlice, BufMut}; +use heapless::LenType; -unsafe impl BufMut for crate::BytesInner { +unsafe impl BufMut for crate::BytesInner { fn remaining_mut(&self) -> usize { self.capacity() - self.len() } diff --git a/src/lib.rs b/src/lib.rs index 1c62841..07f4e79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,17 +15,15 @@ use core::{ cmp::Ordering, fmt::{self, Debug}, hash::{Hash, Hasher}, + marker::PhantomData, ops::{Deref, DerefMut}, }; use heapless::{ - vec::{OwnedVecStorage, Vec as UpstreamVec, VecInner as UpstreamVecInner, ViewVecStorage}, - CapacityError, + vec::{OwnedVecStorage, Vec, VecInner, ViewVecStorage}, + CapacityError, LenType, }; -type VecInner = UpstreamVecInner; -type Vec = UpstreamVec; - use serde::{ de::{Deserialize, Deserializer, Visitor}, ser::{Serialize, Serializer}, @@ -34,7 +32,10 @@ use storage::BytesStorage; mod storage { use super::{BytesInner, BytesView}; - use heapless::vec::{OwnedVecStorage, VecStorage, ViewVecStorage}; + use heapless::{ + vec::{OwnedVecStorage, VecStorage, ViewVecStorage}, + LenType, + }; /// Trait defining how data for a Byte buffer is stored. /// @@ -62,23 +63,27 @@ mod storage { /// [`ViewStorage`]: super::ViewStorage pub trait BytesStorage: BytesStorageSealed {} pub trait BytesStorageSealed: VecStorage { - fn as_byte_view(this: &BytesInner) -> &BytesView + fn as_byte_view(this: &BytesInner) -> &BytesView where Self: BytesStorage; - fn as_byte_mut_view(this: &mut BytesInner) -> &mut BytesView + fn as_byte_mut_view( + this: &mut BytesInner, + ) -> &mut BytesView where Self: BytesStorage; } impl BytesStorage for OwnedVecStorage {} impl BytesStorageSealed for OwnedVecStorage { - fn as_byte_view(this: &BytesInner) -> &BytesView + fn as_byte_view(this: &BytesInner) -> &BytesView where Self: BytesStorage, { this } - fn as_byte_mut_view(this: &mut BytesInner) -> &mut BytesView + fn as_byte_mut_view( + this: &mut BytesInner, + ) -> &mut BytesView where Self: BytesStorage, { @@ -89,13 +94,15 @@ mod storage { impl BytesStorage for ViewVecStorage {} impl BytesStorageSealed for ViewVecStorage { - fn as_byte_view(this: &BytesInner) -> &BytesView + fn as_byte_view(this: &BytesInner) -> &BytesView where Self: BytesStorage, { this } - fn as_byte_mut_view(this: &mut BytesInner) -> &mut BytesView + fn as_byte_mut_view( + this: &mut BytesInner, + ) -> &mut BytesView where Self: BytesStorage, { @@ -107,19 +114,19 @@ mod storage { pub type OwnedBytesStorage = OwnedVecStorage; pub type ViewBytesStorage = ViewVecStorage; -pub struct BytesInner { - bytes: VecInner, +pub struct BytesInner { + bytes: VecInner, } -pub type Bytes = BytesInner>; -pub type BytesView = BytesInner; +pub type Bytes = BytesInner, LenT>; +pub type BytesView = BytesInner; -pub type Bytes8 = Bytes<8>; -pub type Bytes16 = Bytes<16>; -pub type Bytes32 = Bytes<32>; -pub type Bytes64 = Bytes<64>; +pub type Bytes8 = Bytes<8, LenT>; +pub type Bytes16 = Bytes<16, LenT>; +pub type Bytes32 = Bytes<32, LenT>; +pub type Bytes64 = Bytes<64, LenT>; -impl Clone for Bytes { +impl Clone for Bytes { fn clone(&self) -> Self { Self { bytes: self.bytes.clone(), @@ -127,28 +134,28 @@ impl Clone for Bytes { } } -impl Eq for BytesInner {} -impl Ord for BytesInner { +impl Eq for BytesInner {} +impl Ord for BytesInner { fn cmp(&self, other: &Self) -> Ordering { self.bytes.cmp(&other.bytes) } } #[cfg(feature = "heapless-0.9")] -impl From> for Bytes { - fn from(vec: Vec) -> Self { - Bytes { bytes: vec }.increase_capacity() +impl From> for Bytes { + fn from(vec: Vec) -> Self { + Bytes { bytes: vec } } } #[cfg(feature = "heapless-0.9")] -impl From> for Vec { - fn from(value: Bytes) -> Self { - value.increase_capacity().bytes +impl From> for Vec { + fn from(value: Bytes) -> Self { + value.bytes } } -impl TryFrom<&[u8]> for Bytes { +impl TryFrom<&[u8]> for Bytes { type Error = CapacityError; fn try_from(value: &[u8]) -> Result { Ok(Self { @@ -157,13 +164,13 @@ impl TryFrom<&[u8]> for Bytes { } } -impl Default for Bytes { +impl Default for Bytes { fn default() -> Self { Self::new() } } -impl Bytes { +impl Bytes { /// Construct a new, empty `Bytes`. pub const fn new() -> Self { Self { bytes: Vec::new() } @@ -191,7 +198,7 @@ impl Bytes { /// let bytes32: Bytes<32> = Bytes::from([0; 32]); /// let bytes16: Bytes<16> = bytes32.increase_capacity(); /// ``` - pub fn increase_capacity(&self) -> Bytes { + pub fn increase_capacity(&self) -> Bytes { let () = AssertLessThanEq::::ASSERT; let mut bytes = Vec::new(); // bytes has length 0 and capacity M, self has length N, N <= M, so this can never panic @@ -199,18 +206,24 @@ impl Bytes { Bytes { bytes } } - /// Get a "view" to the Buffer with the `N` const generic erased - pub fn as_view(&self) -> &BytesView { - self - } - - /// Get a mutable "view" to the Buffer with the `N` const generic erased - pub fn as_mut_view(&mut self) -> &mut BytesView { - self + pub fn cast_len_type(self) -> Bytes { + BytesInner { + bytes: self.bytes.cast_len_type(), + } } } -impl BytesInner { +impl BytesInner { + /// Get a "view" to the Buffer with the `N` const generic erased + pub fn as_view(&self) -> &BytesView { + S::as_byte_view(self) + } + + /// Get a mutable "view" to the Buffer with the `N` const generic erased + pub fn as_mut_view(&mut self) -> &mut BytesView { + S::as_byte_mut_view(self) + } + pub fn as_ptr(&self) -> *const u8 { self.bytes.as_ptr() } @@ -440,8 +453,6 @@ impl BytesInner { } /// Low-noise conversion between lengths. - /// - /// For an infaillible version when `M` is known to be larger than `N`, see [`increase_capacity`](Self::increase_capacity) pub fn resize_capacity(&self) -> Result, CapacityError> { Bytes::try_from(&**self) } @@ -466,7 +477,7 @@ impl BytesInner { /// # use heapless_bytes::Bytes; /// let bytes: Bytes<3> = Bytes::from([0, 1, 2, 3]); // does not compile /// ``` -impl From<[u8; N]> for Bytes { +impl From<[u8; N]> for Bytes { fn from(bytes: [u8; N]) -> Self { Self::from(&bytes) } @@ -491,7 +502,7 @@ impl AssertLessThanEq { /// # use heapless_bytes::Bytes; /// let bytes: Bytes<3> = Bytes::from(&[0, 1, 2, 3]); // does not compile /// ``` -impl From<&[u8; M]> for Bytes { +impl From<&[u8; M]> for Bytes { fn from(data: &[u8; M]) -> Self { let () = AssertLessThanEq::::ASSERT; let mut bytes = Vec::new(); @@ -501,7 +512,7 @@ impl From<&[u8; M]> for Bytes { } } -impl Debug for BytesInner { +impl Debug for BytesInner { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // TODO: There has to be a better way :'-) @@ -515,19 +526,19 @@ impl Debug for BytesInner { } } -impl AsRef<[u8]> for BytesInner { +impl AsRef<[u8]> for BytesInner { fn as_ref(&self) -> &[u8] { &self.bytes } } -impl AsMut<[u8]> for BytesInner { +impl AsMut<[u8]> for BytesInner { fn as_mut(&mut self) -> &mut [u8] { &mut self.bytes } } -impl Deref for BytesInner { +impl Deref for BytesInner { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -535,13 +546,13 @@ impl Deref for BytesInner { } } -impl DerefMut for BytesInner { +impl DerefMut for BytesInner { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.bytes } } -impl PartialEq for BytesInner +impl PartialEq for BytesInner where Rhs: ?Sized + AsRef<[u8]>, { @@ -550,7 +561,7 @@ where } } -impl PartialOrd for BytesInner +impl PartialOrd for BytesInner where Rhs: ?Sized + AsRef<[u8]>, { @@ -559,27 +570,27 @@ where } } -impl Hash for BytesInner { +impl Hash for BytesInner { fn hash(&self, state: &mut H) { self.bytes.hash(state); } } #[derive(Clone)] -pub struct IntoIter { - inner: as IntoIterator>::IntoIter, +pub struct IntoIter { + inner: as IntoIterator>::IntoIter, } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = u8; fn next(&mut self) -> Option { self.inner.next() } } -impl IntoIterator for Bytes { +impl IntoIterator for Bytes { type Item = u8; - type IntoIter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter { @@ -588,7 +599,7 @@ impl IntoIterator for Bytes { } } -impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a BytesInner { +impl<'a, S: BytesStorage + ?Sized, LenT: LenType> IntoIterator for &'a BytesInner { type Item = &'a u8; type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; @@ -597,7 +608,7 @@ impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a BytesInner { } } -impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a mut BytesInner { +impl<'a, S: BytesStorage + ?Sized, LenT: LenType> IntoIterator for &'a mut BytesInner { type Item = &'a mut u8; type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter; @@ -606,7 +617,7 @@ impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a mut BytesInner { } } -impl Serialize for BytesInner { +impl Serialize for BytesInner { fn serialize(&self, serializer: SER) -> Result where SER: Serializer, @@ -615,7 +626,7 @@ impl Serialize for BytesInner { } } -impl core::fmt::Write for BytesInner { +impl core::fmt::Write for BytesInner { fn write_str(&mut self, s: &str) -> fmt::Result { self.bytes.write_str(s) } @@ -627,15 +638,15 @@ impl core::fmt::Write for BytesInner { } } -impl<'de, const N: usize> Deserialize<'de> for Bytes { +impl<'de, const N: usize, LenT: LenType> Deserialize<'de> for Bytes { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - struct ValueVisitor; + struct ValueVisitor(PhantomData); - impl<'de, const N: usize> Visitor<'de> for ValueVisitor { - type Value = Bytes; + impl<'de, const N: usize, LenT: LenType> Visitor<'de> for ValueVisitor { + type Value = Bytes; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a sequence of bytes") @@ -663,7 +674,7 @@ impl<'de, const N: usize> Deserialize<'de> for Bytes { } } - deserializer.deserialize_bytes(ValueVisitor) + deserializer.deserialize_bytes(ValueVisitor(PhantomData)) } } @@ -711,8 +722,6 @@ mod tests { let _: Bytes<10> = [0; 10].into(); let _: Bytes<10> = (&[0; 8]).into(); #[cfg(feature = "heapless-0.9")] - let _: Bytes<10> = Vec::::new().into(); - #[cfg(feature = "heapless-0.9")] - let _: Bytes<10> = Vec::::new().into(); + let _: Bytes<10> = Vec::::new().into(); } }