mirror of
https://github.com/trussed-dev/heapless-bytes.git
synced 2026-06-20 04:16:33 -07:00
Make everything generic over LenType
This commit is contained in:
+2
-1
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user