Skip to content

Commit

Permalink
bump zerocopy dep; rework Packed stuff to View
Browse files Browse the repository at this point in the history
  • Loading branch information
somethingelseentirely committed Jan 19, 2025
1 parent 74f1561 commit 69bb271
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 681 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description = "A small library abstracting over bytes owning types in an extensi
bytes = { version = "1.6.0", optional = true }
ownedbytes = { version = "0.7.0", optional = true }
memmap2 = { version = "0.9.4", optional = true }
zerocopy = { version = "0.7.35", optional = true, features = ["derive"] }
zerocopy = { version = "0.8.14", optional = true, features = ["derive"] }
pyo3 = {version = "0.23.1", optional = true }

[dev-dependencies]
Expand All @@ -23,3 +23,6 @@ ownedbytes = ["dep:ownedbytes"]
mmap = ["dep:memmap2"]
zerocopy = ["dep:zerocopy"]
pyo3 = ["dep:pyo3"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
80 changes: 49 additions & 31 deletions src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@

use std::any::Any;
use std::ascii::escape_default;
use std::borrow;
use std::borrow::Borrow;
use std::cmp;
use std::fmt;
use std::hash;
use std::ops;
use std::ops::Deref;
use std::slice::SliceIndex;
use std::sync::Arc;
use std::sync::Weak;

fn is_subslice(slice: &[u8], subslice: &[u8]) -> bool {
use crate::erase_lifetime;

pub(crate) fn is_subslice(slice: &[u8], subslice: &[u8]) -> bool {
let slice_start = slice.as_ptr() as usize;
let slice_end = slice_start + slice.len();
let subslice_start = subslice.as_ptr() as usize;
let subslice_end = subslice_start + subslice.len();
subslice_start >= slice_start && subslice_end <= slice_end
}

unsafe fn erase_lifetime<'a>(slice: &'a [u8]) -> &'static [u8] {
&*(slice as *const [u8])
}

pub unsafe trait ByteSource {
type Owner: ByteOwner;

Expand Down Expand Up @@ -56,9 +54,9 @@ impl<T: ByteSource + Sync + Send + 'static> ByteOwner for T {
///
/// See [ByteOwner] for an exhaustive list and more details.
pub struct Bytes {
pub(crate) data: &'static [u8],
data: &'static [u8],
// Actual owner of the bytes.
pub(crate) owner: Arc<dyn ByteOwner>,
owner: Arc<dyn ByteOwner>,
}

/// Weak variant of [Bytes] that doesn't retain the data
Expand All @@ -67,8 +65,8 @@ pub struct Bytes {
/// The referenced subrange of the [Bytes] is reconstructed
/// on [WeakBytes::upgrade].
pub struct WeakBytes {
pub(crate) data: *const [u8],
pub(crate) owner: Weak<dyn ByteOwner>,
data: *const [u8],
owner: Weak<dyn ByteOwner>,
}

// ByteOwner is Send + Sync and Bytes is immutable.
Expand All @@ -86,6 +84,26 @@ impl Clone for Bytes {

// Core implementation of Bytes.
impl Bytes {
#[inline]
pub(crate) unsafe fn get_data(&self) -> &'static [u8] {
self.data
}

#[inline]
pub(crate) unsafe fn set_data(&mut self, data: &'static [u8]) {
self.data = data;
}

#[inline]
pub(crate) fn get_owner(&self) -> Arc<dyn ByteOwner> {
self.owner.clone()
}

#[inline]
pub(crate) fn take_owner(self) -> Arc<dyn ByteOwner> {
self.owner
}

/// Creates an empty `Bytes`.
#[inline]
pub fn empty() -> Self {
Expand Down Expand Up @@ -203,14 +221,7 @@ impl<T: ByteSource + ByteOwner> From<Arc<T>> for Bytes {
}
}

impl AsRef<[u8]> for Bytes {
#[inline]
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}

impl ops::Deref for Bytes {
impl Deref for Bytes {
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
Expand All @@ -221,15 +232,22 @@ impl ops::Deref for Bytes {
#[cfg(feature = "ownedbytes")]
unsafe impl ownedbytes::StableDeref for Bytes {}

impl hash::Hash for Bytes {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_slice().hash(state);
impl Borrow<[u8]> for Bytes {
fn borrow(&self) -> &[u8] {
self
}
}

impl borrow::Borrow<[u8]> for Bytes {
fn borrow(&self) -> &[u8] {
self.as_slice()
impl AsRef<[u8]> for Bytes {
#[inline]
fn as_ref(&self) -> &[u8] {
self
}
}

impl hash::Hash for Bytes {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_slice().hash(state);
}
}

Expand All @@ -239,17 +257,17 @@ impl Default for Bytes {
}
}

impl<T: AsRef<[u8]>> PartialEq<T> for Bytes {
fn eq(&self, other: &T) -> bool {
self.as_slice() == other.as_ref()
impl PartialEq for Bytes {
fn eq(&self, other: &Self) -> bool {
self.as_slice() == other.as_slice()
}
}

impl Eq for Bytes {}

impl<T: AsRef<[u8]>> PartialOrd<T> for Bytes {
fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
self.as_slice().partial_cmp(other.as_ref())
impl PartialOrd for Bytes {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.as_slice().partial_cmp(other.as_slice())
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod bytes;
mod owners;

#[cfg(feature = "zerocopy")]
pub mod packed;
pub mod view;

#[cfg(feature = "pyo3")]
pub mod pybytes;
Expand All @@ -25,10 +25,10 @@ pub use crate::bytes::ByteSource;
pub use crate::bytes::Bytes;
pub use crate::bytes::WeakBytes;
#[cfg(feature = "zerocopy")]
pub use crate::packed::Packed;
#[cfg(feature = "zerocopy")]
pub use crate::packed::PackedSlice;
#[cfg(feature = "zerocopy")]
pub use crate::packed::PackedStr;
pub use crate::view::View;
#[cfg(feature = "pyo3")]
pub use crate::pybytes::PyBytes;

unsafe fn erase_lifetime<'a, T: ?Sized>(slice: &'a T) -> &'static T {
&*(slice as *const T)
}
19 changes: 10 additions & 9 deletions src/owners.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
* LICENSE file in the root directory of this source tree.
*/

use zerocopy::Immutable;
#[cfg(feature = "zerocopy")]
use zerocopy::AsBytes;
use zerocopy::IntoBytes;

#[allow(unused_imports)]
use crate::{bytes::ByteOwner, ByteSource};

#[cfg(feature = "zerocopy")]
unsafe impl<T> ByteSource for &'static [T]
where
T: AsBytes + Sync + Send + 'static,
T: IntoBytes + Immutable + Sync + Send + 'static,
{
type Owner = Self;

fn as_bytes(&self) -> &[u8] {
AsBytes::as_bytes(*self)
IntoBytes::as_bytes(*self)
}

fn get_owner(self) -> Self::Owner {
Expand All @@ -43,13 +45,13 @@ unsafe impl ByteSource for &'static [u8] {
#[cfg(feature = "zerocopy")]
unsafe impl<T> ByteSource for Box<T>
where
T: AsBytes + ?Sized + Sync + Send + 'static,
T: IntoBytes + Immutable + ?Sized + Sync + Send + 'static,
{
type Owner = Self;

fn as_bytes(&self) -> &[u8] {
let inner = self.as_ref();
AsBytes::as_bytes(inner)
IntoBytes::as_bytes(inner)
}

fn get_owner(self) -> Self::Owner {
Expand All @@ -73,13 +75,13 @@ unsafe impl ByteSource for Box<[u8]> {
#[cfg(feature = "zerocopy")]
unsafe impl<T> ByteSource for Vec<T>
where
T: AsBytes + Sync + Send + 'static,
T: IntoBytes + Immutable + Sync + Send + 'static,
{
type Owner = Self;

fn as_bytes(&self) -> &[u8] {
let slice: &[T] = self.as_ref();
AsBytes::as_bytes(slice)
IntoBytes::as_bytes(slice)
}

fn get_owner(self) -> Self::Owner {
Expand Down Expand Up @@ -182,7 +184,6 @@ unsafe impl<'py> ByteSource for pyo3::Bound<'py, pyo3::types::PyBytes> {
self.unbind()
}
}

#[cfg(kani)]
mod verification {
use std::sync::Arc;
Expand Down Expand Up @@ -214,7 +215,7 @@ mod verification {
}

#[cfg(feature = "zerocopy")]
#[derive(zerocopy::FromZeroes, zerocopy::FromBytes, zerocopy::AsBytes, Clone, Copy)]
#[derive(zerocopy::FromZeroes, zerocopy::FromBytes, zerocopy::IntoBytes, Clone, Copy)]
#[repr(C)]
struct ComplexZC {
a: u64,
Expand Down
99 changes: 0 additions & 99 deletions src/packed.rs

This file was deleted.

Loading

0 comments on commit 69bb271

Please sign in to comment.