Skip to content

Commit d700f35

Browse files
committed
add Bytes::with_impl and related trait
1 parent 49b2a1c commit d700f35

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/bytes.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,32 @@ pub struct Bytes {
104104
data: AtomicPtr<()>,
105105
vtable: &'static Vtable,
106106
}
107+
/// A trait for underlying implementations for `Bytes` type.
108+
///
109+
/// All implementations must fulfill the following requirements:
110+
/// - They are cheaply cloneable and thereby shareable between an unlimited amount
111+
/// of components, for example by modifying a reference count.
112+
/// - Instances can be sliced to refer to a subset of the the original buffer.
113+
pub unsafe trait BytesImpl: 'static {
114+
/// Decompose `Self` into parts used by `Bytes`.
115+
fn into_bytes_parts(this: Self) -> (AtomicPtr<()>, *const u8, usize);
116+
117+
/// Returns new `Bytes` based on the current parts.
118+
unsafe fn clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes;
119+
120+
/// Called before the `Bytes::truncate` is processed.
121+
/// Useful if the implementation needs some preparation step for it.
122+
unsafe fn will_truncate(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
123+
// do nothing by default
124+
let _ = (data, ptr, len);
125+
}
126+
127+
/// Consumes underlying resources and return `Vec<u8>`
128+
unsafe fn into_vec(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8>;
129+
130+
/// Release underlying resources.
131+
unsafe fn drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize);
132+
}
107133

108134
pub(crate) struct Vtable {
109135
/// fn(data, ptr, len)
@@ -115,7 +141,7 @@ pub(crate) struct Vtable {
115141
pub will_truncate: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
116142
/// fn(data, ptr, len)
117143
///
118-
/// Consumes `Bytes` to return `Vec<u8>`
144+
/// Consumes `Bytes` and return `Vec<u8>`
119145
pub into_vec: unsafe fn(&mut AtomicPtr<()>, *const u8, usize) -> Vec<u8>,
120146
/// fn(data, ptr, len)
121147
pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
@@ -183,6 +209,26 @@ impl Bytes {
183209
}
184210
}
185211

212+
/// Creates a new `Bytes` from `BytesImpl` implementation.
213+
///
214+
/// Useful if you want to construct `Bytes` from your own buffer implementation.
215+
#[inline]
216+
pub fn with_impl<T: BytesImpl>(bytes_impl: T) -> Bytes {
217+
let (data, ptr, len) = BytesImpl::into_bytes_parts(bytes_impl);
218+
219+
Bytes {
220+
ptr,
221+
len,
222+
data,
223+
vtable: &Vtable {
224+
clone: T::clone,
225+
will_truncate: T::will_truncate,
226+
into_vec: T::into_vec,
227+
drop: T::drop,
228+
},
229+
}
230+
}
231+
186232
/// Returns the number of bytes contained in this `Bytes`.
187233
///
188234
/// # Examples

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ mod bytes;
8787
mod bytes_mut;
8888
mod fmt;
8989
mod loom;
90-
pub use crate::bytes::Bytes;
90+
pub use crate::bytes::{Bytes, BytesImpl};
9191
pub use crate::bytes_mut::BytesMut;
9292

9393
// Optional Serde support

0 commit comments

Comments
 (0)