use crate::buf::Slice;
use std::ops;
pub unsafe trait IoBuf: Unpin + 'static {
fn stable_ptr(&self) -> *const u8;
fn bytes_init(&self) -> usize;
fn bytes_total(&self) -> usize;
fn slice(self, range: impl ops::RangeBounds<usize>) -> Slice<Self>
where
Self: Sized,
{
use core::ops::Bound;
let begin = match range.start_bound() {
Bound::Included(&n) => n,
Bound::Excluded(&n) => n + 1,
Bound::Unbounded => 0,
};
assert!(begin < self.bytes_total());
let end = match range.end_bound() {
Bound::Included(&n) => n.checked_add(1).expect("out of range"),
Bound::Excluded(&n) => n,
Bound::Unbounded => self.bytes_total(),
};
assert!(end <= self.bytes_total());
assert!(begin <= self.bytes_init());
Slice::new(self, begin, end)
}
}
unsafe impl IoBuf for Vec<u8> {
fn stable_ptr(&self) -> *const u8 {
self.as_ptr()
}
fn bytes_init(&self) -> usize {
self.len()
}
fn bytes_total(&self) -> usize {
self.capacity()
}
}
unsafe impl IoBuf for &'static [u8] {
fn stable_ptr(&self) -> *const u8 {
self.as_ptr()
}
fn bytes_init(&self) -> usize {
<[u8]>::len(self)
}
fn bytes_total(&self) -> usize {
self.bytes_init()
}
}
unsafe impl IoBuf for &'static str {
fn stable_ptr(&self) -> *const u8 {
self.as_ptr()
}
fn bytes_init(&self) -> usize {
<str>::len(self)
}
fn bytes_total(&self) -> usize {
self.bytes_init()
}
}
#[cfg(feature = "bytes")]
unsafe impl IoBuf for bytes::Bytes {
fn stable_ptr(&self) -> *const u8 {
self.as_ptr()
}
fn bytes_init(&self) -> usize {
self.len()
}
fn bytes_total(&self) -> usize {
self.len()
}
}
#[cfg(feature = "bytes")]
unsafe impl IoBuf for bytes::BytesMut {
fn stable_ptr(&self) -> *const u8 {
self.as_ptr()
}
fn bytes_init(&self) -> usize {
self.len()
}
fn bytes_total(&self) -> usize {
self.capacity()
}
}