Make everything generic over LenType

This commit is contained in:
Sosthène Guédon
2025-04-30 10:45:32 +02:00
parent 1ea22be155
commit 10ed778672
2 changed files with 82 additions and 72 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
use crate::storage::BytesStorage;
use bytes::{buf::UninitSlice, BufMut};
use heapless::LenType;
unsafe impl<S: BytesStorage + ?Sized> BufMut for crate::BytesInner<S> {
unsafe impl<S: BytesStorage + ?Sized, LenT: LenType> BufMut for crate::BytesInner<S, LenT> {
fn remaining_mut(&self) -> usize {
self.capacity() - self.len()
}
+80 -71
View File
@@ -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<T, S> = UpstreamVecInner<T, usize, S>;
type Vec<T, const N: usize> = UpstreamVec<T, N, usize>;
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<u8> {
fn as_byte_view(this: &BytesInner<Self>) -> &BytesView
fn as_byte_view<LenT: LenType>(this: &BytesInner<Self, LenT>) -> &BytesView<LenT>
where
Self: BytesStorage;
fn as_byte_mut_view(this: &mut BytesInner<Self>) -> &mut BytesView
fn as_byte_mut_view<LenT: LenType>(
this: &mut BytesInner<Self, LenT>,
) -> &mut BytesView<LenT>
where
Self: BytesStorage;
}
impl<const N: usize> BytesStorage for OwnedVecStorage<u8, N> {}
impl<const N: usize> BytesStorageSealed for OwnedVecStorage<u8, N> {
fn as_byte_view(this: &BytesInner<Self>) -> &BytesView
fn as_byte_view<LenT: LenType>(this: &BytesInner<Self, LenT>) -> &BytesView<LenT>
where
Self: BytesStorage,
{
this
}
fn as_byte_mut_view(this: &mut BytesInner<Self>) -> &mut BytesView
fn as_byte_mut_view<LenT: LenType>(
this: &mut BytesInner<Self, LenT>,
) -> &mut BytesView<LenT>
where
Self: BytesStorage,
{
@@ -89,13 +94,15 @@ mod storage {
impl BytesStorage for ViewVecStorage<u8> {}
impl BytesStorageSealed for ViewVecStorage<u8> {
fn as_byte_view(this: &BytesInner<Self>) -> &BytesView
fn as_byte_view<LenT: LenType>(this: &BytesInner<Self, LenT>) -> &BytesView<LenT>
where
Self: BytesStorage,
{
this
}
fn as_byte_mut_view(this: &mut BytesInner<Self>) -> &mut BytesView
fn as_byte_mut_view<LenT: LenType>(
this: &mut BytesInner<Self, LenT>,
) -> &mut BytesView<LenT>
where
Self: BytesStorage,
{
@@ -107,19 +114,19 @@ mod storage {
pub type OwnedBytesStorage<const N: usize> = OwnedVecStorage<u8, N>;
pub type ViewBytesStorage = ViewVecStorage<u8>;
pub struct BytesInner<S: BytesStorage + ?Sized> {
bytes: VecInner<u8, S>,
pub struct BytesInner<S: BytesStorage + ?Sized, LenT: LenType> {
bytes: VecInner<u8, LenT, S>,
}
pub type Bytes<const N: usize> = BytesInner<OwnedBytesStorage<N>>;
pub type BytesView = BytesInner<ViewBytesStorage>;
pub type Bytes<const N: usize, LenT = usize> = BytesInner<OwnedBytesStorage<N>, LenT>;
pub type BytesView<LenT = usize> = BytesInner<ViewBytesStorage, LenT>;
pub type Bytes8 = Bytes<8>;
pub type Bytes16 = Bytes<16>;
pub type Bytes32 = Bytes<32>;
pub type Bytes64 = Bytes<64>;
pub type Bytes8<LenT = usize> = Bytes<8, LenT>;
pub type Bytes16<LenT = usize> = Bytes<16, LenT>;
pub type Bytes32<LenT = usize> = Bytes<32, LenT>;
pub type Bytes64<LenT = usize> = Bytes<64, LenT>;
impl<const N: usize> Clone for Bytes<N> {
impl<const N: usize, LenT: LenType> Clone for Bytes<N, LenT> {
fn clone(&self) -> Self {
Self {
bytes: self.bytes.clone(),
@@ -127,28 +134,28 @@ impl<const N: usize> Clone for Bytes<N> {
}
}
impl<S: BytesStorage + ?Sized> Eq for BytesInner<S> {}
impl<S: BytesStorage + ?Sized> Ord for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> Eq for BytesInner<S, LenT> {}
impl<S: BytesStorage + ?Sized, LenT: LenType> Ord for BytesInner<S, LenT> {
fn cmp(&self, other: &Self) -> Ordering {
self.bytes.cmp(&other.bytes)
}
}
#[cfg(feature = "heapless-0.9")]
impl<const N: usize, const M: usize> From<Vec<u8, M>> for Bytes<N> {
fn from(vec: Vec<u8, M>) -> Self {
Bytes { bytes: vec }.increase_capacity()
impl<const N: usize, LenT: LenType> From<Vec<u8, N, LenT>> for Bytes<N, LenT> {
fn from(vec: Vec<u8, N, LenT>) -> Self {
Bytes { bytes: vec }
}
}
#[cfg(feature = "heapless-0.9")]
impl<const N: usize, const M: usize> From<Bytes<M>> for Vec<u8, N> {
fn from(value: Bytes<M>) -> Self {
value.increase_capacity().bytes
impl<const N: usize, LenT: LenType> From<Bytes<N, LenT>> for Vec<u8, N, LenT> {
fn from(value: Bytes<N, LenT>) -> Self {
value.bytes
}
}
impl<const N: usize> TryFrom<&[u8]> for Bytes<N> {
impl<const N: usize, LenT: LenType> TryFrom<&[u8]> for Bytes<N, LenT> {
type Error = CapacityError;
fn try_from(value: &[u8]) -> Result<Self, CapacityError> {
Ok(Self {
@@ -157,13 +164,13 @@ impl<const N: usize> TryFrom<&[u8]> for Bytes<N> {
}
}
impl<const N: usize> Default for Bytes<N> {
impl<const N: usize, LenT: LenType> Default for Bytes<N, LenT> {
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> Bytes<N> {
impl<const N: usize, LenT: LenType> Bytes<N, LenT> {
/// Construct a new, empty `Bytes<N>`.
pub const fn new() -> Self {
Self { bytes: Vec::new() }
@@ -191,7 +198,7 @@ impl<const N: usize> Bytes<N> {
/// let bytes32: Bytes<32> = Bytes::from([0; 32]);
/// let bytes16: Bytes<16> = bytes32.increase_capacity();
/// ```
pub fn increase_capacity<const M: usize>(&self) -> Bytes<M> {
pub fn increase_capacity<const M: usize>(&self) -> Bytes<M, LenT> {
let () = AssertLessThanEq::<N, M>::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<const N: usize> Bytes<N> {
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<NewLenT: LenType>(self) -> Bytes<N, NewLenT> {
BytesInner {
bytes: self.bytes.cast_len_type(),
}
}
}
impl<S: BytesStorage + ?Sized> BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> BytesInner<S, LenT> {
/// Get a "view" to the Buffer with the `N` const generic erased
pub fn as_view(&self) -> &BytesView<LenT> {
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<LenT> {
S::as_byte_mut_view(self)
}
pub fn as_ptr(&self) -> *const u8 {
self.bytes.as_ptr()
}
@@ -440,8 +453,6 @@ impl<S: BytesStorage + ?Sized> BytesInner<S> {
}
/// 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<const M: usize>(&self) -> Result<Bytes<M>, CapacityError> {
Bytes::try_from(&**self)
}
@@ -466,7 +477,7 @@ impl<S: BytesStorage + ?Sized> BytesInner<S> {
/// # use heapless_bytes::Bytes;
/// let bytes: Bytes<3> = Bytes::from([0, 1, 2, 3]); // does not compile
/// ```
impl<const N: usize> From<[u8; N]> for Bytes<N> {
impl<const N: usize, LenT: LenType> From<[u8; N]> for Bytes<N, LenT> {
fn from(bytes: [u8; N]) -> Self {
Self::from(&bytes)
}
@@ -491,7 +502,7 @@ impl<const I: usize, const J: usize> AssertLessThanEq<I, J> {
/// # use heapless_bytes::Bytes;
/// let bytes: Bytes<3> = Bytes::from(&[0, 1, 2, 3]); // does not compile
/// ```
impl<const N: usize, const M: usize> From<&[u8; M]> for Bytes<N> {
impl<const N: usize, const M: usize, LenT: LenType> From<&[u8; M]> for Bytes<N, LenT> {
fn from(data: &[u8; M]) -> Self {
let () = AssertLessThanEq::<M, N>::ASSERT;
let mut bytes = Vec::new();
@@ -501,7 +512,7 @@ impl<const N: usize, const M: usize> From<&[u8; M]> for Bytes<N> {
}
}
impl<S: BytesStorage + ?Sized> Debug for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> Debug for BytesInner<S, LenT> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// TODO: There has to be a better way :'-)
@@ -515,19 +526,19 @@ impl<S: BytesStorage + ?Sized> Debug for BytesInner<S> {
}
}
impl<S: BytesStorage + ?Sized> AsRef<[u8]> for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> AsRef<[u8]> for BytesInner<S, LenT> {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl<S: BytesStorage + ?Sized> AsMut<[u8]> for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> AsMut<[u8]> for BytesInner<S, LenT> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.bytes
}
}
impl<S: BytesStorage + ?Sized> Deref for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> Deref for BytesInner<S, LenT> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
@@ -535,13 +546,13 @@ impl<S: BytesStorage + ?Sized> Deref for BytesInner<S> {
}
}
impl<S: BytesStorage + ?Sized> DerefMut for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> DerefMut for BytesInner<S, LenT> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.bytes
}
}
impl<Rhs, S: BytesStorage + ?Sized> PartialEq<Rhs> for BytesInner<S>
impl<Rhs, S: BytesStorage + ?Sized, LenT: LenType> PartialEq<Rhs> for BytesInner<S, LenT>
where
Rhs: ?Sized + AsRef<[u8]>,
{
@@ -550,7 +561,7 @@ where
}
}
impl<Rhs, S: BytesStorage + ?Sized> PartialOrd<Rhs> for BytesInner<S>
impl<Rhs, S: BytesStorage + ?Sized, LenT: LenType> PartialOrd<Rhs> for BytesInner<S, LenT>
where
Rhs: ?Sized + AsRef<[u8]>,
{
@@ -559,27 +570,27 @@ where
}
}
impl<S: BytesStorage + ?Sized> Hash for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> Hash for BytesInner<S, LenT> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.bytes.hash(state);
}
}
#[derive(Clone)]
pub struct IntoIter<const N: usize> {
inner: <Vec<u8, N> as IntoIterator>::IntoIter,
pub struct IntoIter<const N: usize, LenT: LenType = usize> {
inner: <Vec<u8, N, LenT> as IntoIterator>::IntoIter,
}
impl<const N: usize> Iterator for IntoIter<N> {
impl<const N: usize, LenT: LenType> Iterator for IntoIter<N, LenT> {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<const N: usize> IntoIterator for Bytes<N> {
impl<const N: usize, LenT: LenType> IntoIterator for Bytes<N, LenT> {
type Item = u8;
type IntoIter = IntoIter<N>;
type IntoIter = IntoIter<N, LenT>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
@@ -588,7 +599,7 @@ impl<const N: usize> IntoIterator for Bytes<N> {
}
}
impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a BytesInner<S> {
impl<'a, S: BytesStorage + ?Sized, LenT: LenType> IntoIterator for &'a BytesInner<S, LenT> {
type Item = &'a u8;
type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
@@ -597,7 +608,7 @@ impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a BytesInner<S> {
}
}
impl<'a, S: BytesStorage + ?Sized> IntoIterator for &'a mut BytesInner<S> {
impl<'a, S: BytesStorage + ?Sized, LenT: LenType> IntoIterator for &'a mut BytesInner<S, LenT> {
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<S> {
}
}
impl<S: BytesStorage + ?Sized> Serialize for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> Serialize for BytesInner<S, LenT> {
fn serialize<SER>(&self, serializer: SER) -> Result<SER::Ok, SER::Error>
where
SER: Serializer,
@@ -615,7 +626,7 @@ impl<S: BytesStorage + ?Sized> Serialize for BytesInner<S> {
}
}
impl<S: BytesStorage + ?Sized> core::fmt::Write for BytesInner<S> {
impl<S: BytesStorage + ?Sized, LenT: LenType> core::fmt::Write for BytesInner<S, LenT> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.bytes.write_str(s)
}
@@ -627,15 +638,15 @@ impl<S: BytesStorage + ?Sized> core::fmt::Write for BytesInner<S> {
}
}
impl<'de, const N: usize> Deserialize<'de> for Bytes<N> {
impl<'de, const N: usize, LenT: LenType> Deserialize<'de> for Bytes<N, LenT> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<const N: usize>;
struct ValueVisitor<const N: usize, LenT: LenType>(PhantomData<LenT>);
impl<'de, const N: usize> Visitor<'de> for ValueVisitor<N> {
type Value = Bytes<N>;
impl<'de, const N: usize, LenT: LenType> Visitor<'de> for ValueVisitor<N, LenT> {
type Value = Bytes<N, LenT>;
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<N> {
}
}
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::<u8, 10>::new().into();
#[cfg(feature = "heapless-0.9")]
let _: Bytes<10> = Vec::<u8, 9>::new().into();
let _: Bytes<10> = Vec::<u8, 10, usize>::new().into();
}
}