From 39de561b86bdab6e85f1c26080590f37ccd36b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 10 Apr 2025 15:35:43 +0200 Subject: [PATCH] Implement the bytes traits --- Cargo.toml | 2 ++ src/bytes_traits.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 ++ 3 files changed, 79 insertions(+) create mode 100644 src/bytes_traits.rs diff --git a/Cargo.toml b/Cargo.toml index d24a804..b96b1ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ edition = "2021" [dependencies] heapless = { version = "0.9.1", default-features = false } +bytes = { version = "1.10.1", default-features = false, optional = true } serde = { version = "1.0", default-features = false } [dev-dependencies] @@ -20,3 +21,4 @@ serde_test = "1.0.176" [features] "heapless-0.9" = [] +bytes = ["dep:bytes"] diff --git a/src/bytes_traits.rs b/src/bytes_traits.rs new file mode 100644 index 0000000..31b9817 --- /dev/null +++ b/src/bytes_traits.rs @@ -0,0 +1,74 @@ +use crate::storage::BytesStorage; +use bytes::{buf::UninitSlice, BufMut}; +use heapless::LenType; + +unsafe impl BufMut for crate::BytesInner { + fn remaining_mut(&self) -> usize { + self.capacity() - self.len() + } + unsafe fn advance_mut(&mut self, cnt: usize) { + self.set_len(cnt); + } + fn chunk_mut(&mut self) -> &mut UninitSlice { + // SAFETY: add is safe because once the length is added is less than the buffer and therefore + // always in the "allocation" bounds + let ptr = unsafe { self.bytes.as_mut_ptr().add(self.len()) }; + let len = self.capacity() - self.len(); + unsafe { UninitSlice::from_raw_parts_mut(ptr, len) } + } +} + +#[cfg(test)] +mod tests { + use crate::{Bytes, BytesView}; + use bytes::BufMut; + + #[test] + #[should_panic] + fn buf_mut_advance_mut_out_of_bounds() { + let mut bytes: Bytes<8> = Bytes::new(); + unsafe { bytes.advance_mut(9) }; + } + + #[test] + fn buf_mut_remaining_mut() { + let mut bytes: Bytes<8> = Bytes::new(); + assert_eq!(bytes.remaining_mut(), 8); + bytes.push(42).unwrap(); + assert_eq!(bytes.remaining_mut(), 7); + } + + #[test] + fn buf_mut_chunk_mut() { + let mut bytes: Bytes<8> = Bytes::new(); + assert_eq!(bytes.chunk_mut().len(), 8); + unsafe { bytes.advance_mut(1) }; + assert_eq!(bytes.chunk_mut().len(), 7); + } + + #[test] + #[should_panic] + fn view_buf_mut_advance_mut_out_of_bounds() { + let mut bytes: Bytes<8> = Bytes::new(); + let bytes: &mut BytesView = &mut bytes; + unsafe { bytes.advance_mut(9) }; + } + + #[test] + fn view_buf_mut_remaining_mut() { + let mut bytes: Bytes<8> = Bytes::new(); + let bytes: &mut BytesView = &mut bytes; + assert_eq!(bytes.remaining_mut(), 8); + bytes.push(42).unwrap(); + assert_eq!(bytes.remaining_mut(), 7); + } + + #[test] + fn view_buf_mut_chunk_mut() { + let mut bytes: Bytes<8> = Bytes::new(); + let bytes: &mut BytesView = &mut bytes; + assert_eq!(bytes.chunk_mut().len(), 8); + unsafe { bytes.advance_mut(1) }; + assert_eq!(bytes.chunk_mut().len(), 7); + } +} diff --git a/src/lib.rs b/src/lib.rs index 5f09b0c..3fdb4d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,9 @@ #![cfg_attr(not(test), no_std)] #![allow(clippy::result_unit_err)] +#[cfg(feature = "bytes")] +mod bytes_traits; + use core::{ cmp::Ordering, fmt::{self, Debug},