Skip to content

Commit

Permalink
v0.1.7: bytedata union at 16 bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLuq committed Jul 29, 2024
1 parent 0e3c056 commit 2502a89
Show file tree
Hide file tree
Showing 28 changed files with 678 additions and 271 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "bytedata"
version = "0.1.6"
version = "0.1.7"
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.75.0"
description = "Representation of a byte slice that is either static, borrowed, or shared."
license = "MIT OR LGPL-3.0-or-later"
repository = "https://github.com/TimLuq/bytedata/"
Expand All @@ -27,7 +27,7 @@ chunk = []
macros = []
nightly = []
queue = []
read_buf = ["std"]
core_io_borrowed_buf = []
std = ["alloc"]
bytes_1 = ["dep:bytes_1"]

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# bytedata

A library for working with byte arrays in a `const`-friendly manner.
A library for working with byte slices in a `const`-friendly manner.

When the `alloc` feature is enabled this crate provides `SharedBytes` which operates like `Arc<[u8]>` but with a representation that allows for `const` references to the bytes and zero-copy subslicing.
The `SharedBytes` type is then also added as one additional representation of `ByteData`.
Expand All @@ -15,7 +15,7 @@ This allows for dynamic allocation of byte arrays which are exposed as `SharedBy
### chunk

Enables runtime representation of small byte arrays inline as `ByteData::Chunk(_)`.
This allows for optimized storage of small byte arrays that are less than or equal to 12 bytes in size.
This allows for optimized storage of small byte arrays that are less than or equal to 14 bytes in size.

### macros

Expand All @@ -25,20 +25,20 @@ These macros allow for concatenation of static byte arrays and strings that are

### bytes_1

Enables integration with the `bytes` crate (version `>=1.2, <2`).
Enables integration with the `bytes` crate (version `>=1.6.1, <2`).
This allows for conversion between `SharedBytes` and `bytes::Bytes` types.
Where possible no bytes will be cloned, which means that `ByteData::Static(_)` will map to `bytes::Bytes::from_static`,
and that `<bytes::Bytes as From<SharedBytes>>::from` will return a `bytes::Bytes` object that is just a wrapper and still share the bytes as normal without any copy.
and that `<bytes::Bytes as From<SharedBytes>>::from` will return a `bytes::Bytes` object that is just a wrapper and still share the bytes as normal without any copying.

There is, however, a possibility that the internal vtable or structure of `bytes::Bytes` changes in the future, in which case the zero-copy may break or segfault.
If this happens you can enable the feature `bytes_1_safe` which will always cause the bytes to be cloned when converting to and from `bytes::Bytes` without the use of any internal structures.

### bytes_1_safe

Enables integration with the `bytes` crate (version `>=1.2, <2`) in a safe manner.
Enables integration with the `bytes` crate (version `>=1.6.1, <2`) in a safe manner.
This will cause the bytes to always be cloned when converting to and from `bytes::Bytes`.

For zero-copy conversion between `SharedBytes` and `bytes::Bytes`, use the `bytes_1` feature instead unless it is broken.
For zero-copy conversion between `SharedBytes` and `bytes::Bytes`, use the `bytes_1` feature instead - unless it is broken.

### http-body_04

Expand Down
1 change: 1 addition & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[toolchain]
channel = "nightly"
#channel = "1.75"
10 changes: 5 additions & 5 deletions src/byte_chunk.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use core::{ops::RangeBounds, slice::SliceIndex};

/// A chunk of bytes that is 12 bytes or less.
/// A chunk of bytes that is 14 bytes or less.
#[cfg_attr(docsrs, doc(cfg(feature = "chunk")))]
#[derive(Clone, Copy)]
pub struct ByteChunk {
/// The length of the chunk.
pub(crate) len: u8,
/// The data of the chunk.
pub(crate) data: [u8; Self::LEN],
pub(crate) data: [u8; 14],
}

impl ByteChunk {
/// The maximum length of a `ByteChunk`.
pub const LEN: usize = 12;
pub const LEN: usize = 14;

/// Create a `ByteChunk` from a slice.
pub const fn from_slice(data: &[u8]) -> Self {
Expand All @@ -32,7 +32,7 @@ impl ByteChunk {

/// Create a `ByteChunk` from a fixed-size array.
pub const fn from_array<const L: usize>(data: &[u8; L]) -> Self {
core::assert!(L <= 12, "chunk data too large");
core::assert!(L <= 14, "chunk data too large");
let mut chunk = ByteChunk {
len: L as u8,
data: unsafe { core::mem::zeroed() },
Expand Down Expand Up @@ -159,7 +159,7 @@ impl Default for ByteChunk {
fn default() -> Self {
ByteChunk {
len: 0,
data: [0; 12],
data: [0; 14],
}
}
}
18 changes: 13 additions & 5 deletions src/byte_string_render.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/// Helper wrapper to render a byte slice as a bytestring similar to [`core::ascii::escape_default`].
///
/// ```ignore
#[cfg_attr(feature = "alloc", doc = "```")]
#[cfg_attr(not(feature = "alloc"), doc = "```ignore")]
/// # extern crate alloc;
/// # use alloc::format;
/// # use bytedata::ByteStringRender;
/// format!("{}", ByteStringRender::from_slice(b"Hello,\nWorld!"));
/// // => "Hello,\\nWorld!"
/// format!("{:?}", ByteStringRender::from_slice(b"Hello,\nWorld!"));
Expand Down Expand Up @@ -77,10 +81,14 @@ impl<'a> core::fmt::Display for ByteStringRender<'a> {

/// Helper wrapper to render a byte slice as a bytestring similar to [`core::ascii::escape_default`].
///
/// ```ignore
/// format!("{}", MultiByteStringRender::new(&[b"Hello,\nWorld!"]));
#[cfg_attr(feature = "alloc", doc = "```")]
#[cfg_attr(not(feature = "alloc"), doc = "```ignore")]
/// # extern crate alloc;
/// # use alloc::format;
/// # use bytedata::MultiByteStringRender;
/// format!("{}", MultiByteStringRender::new(&[b"Hello,\n".as_slice(), b"World!"]));
/// // => "Hello,\\nWorld!"
/// format!("{:?}", MultiByteStringRender::new(&[b"Hello,\nWorld!"]));
/// format!("{:?}", MultiByteStringRender::new(&[b"Hello,\n".as_slice(), b"World!"]));
/// // => "b\"Hello,\\nWorld!\""
/// ```
pub struct MultiByteStringRender<'a, T, R> {
Expand All @@ -92,7 +100,7 @@ impl<'a, T, R: AsRef<[u8]>> MultiByteStringRender<'a, T, R>
where
&'a T: IntoIterator<Item = R>,
{
/// Create a new `ByteStringRender` from a byte slice.
/// Create a new `MultiByteStringRender` from an iterator over byte slices.
pub const fn new(inner: &'a T) -> Self {
Self {
inner,
Expand Down
Loading

0 comments on commit 2502a89

Please sign in to comment.