Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update bytes features with lasted bytes version 1.1.0 & add edition 2021 #12

Merged
merged 1 commit into from Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Expand Up @@ -13,8 +13,9 @@ edition = "2021"

[features]

[dependencies]
bytes = { version = "0.5", optional = true }
[dependencies.bytes]
version = "1.1.0"
optional = true

[dev-dependencies]
vecio = "0.1.0"
Expand Down
158 changes: 158 additions & 0 deletions src/bytes.rs
@@ -0,0 +1,158 @@
use std::io::IoSlice;

use crate::CircBuf;

use bytes::{buf::UninitSlice, Buf, BufMut};

impl Buf for CircBuf {
fn advance(&mut self, count: usize) {
assert!(count == 0 || count <= self.remaining());
self.advance_read(count);
}

fn chunk(&self) -> &[u8] {
let [left, right] = self.get_bytes();
match (left.is_empty(), right.is_empty()) {
(true, true) => left,
(true, false) => right,
(false, true) => left,
(false, false) => left,
}
}

fn remaining(&self) -> usize {
self.len()
}

fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
let [left, right] = self.get_bytes();
let mut count = 0;
if let Some(slice) = dst.get_mut(0) {
count += 1;
*slice = IoSlice::new(left);
}
if let Some(slice) = dst.get_mut(1) {
count += 1;
*slice = IoSlice::new(right);
}
count
}
}

unsafe impl BufMut for CircBuf {
jeromefroe marked this conversation as resolved.
Show resolved Hide resolved
unsafe fn advance_mut(&mut self, count: usize) {
assert!(count == 0 || count <= self.remaining_mut());
self.advance_write(count);
}

fn chunk_mut<'this>(&'this mut self) -> &'this mut UninitSlice {
let [left, right] = self.get_avail();
let slice = match (left.is_empty(), right.is_empty()) {
(true, true) => left,
(true, false) => right,
(false, true) => left,
(false, false) => left,
};
// https://docs.rs/bytes/latest/bytes/buf/struct.UninitSlice.html#method.from_raw_parts_mut
unsafe { UninitSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) }
}

fn remaining_mut(&self) -> usize {
self.avail()
}
}

#[cfg(test)]
mod tests {
use crate::CircBuf;
use bytes::{Buf, BufMut};
use std::io::IoSlice;

#[test]
fn bytes_buf_and_bufmut() {
let mut c = CircBuf::with_capacity(4).unwrap();

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
unsafe {
c.advance_mut(2);
}
assert_eq!(c.remaining(), 2);
assert_eq!(c.remaining_mut(), 1);
c.advance(1);
assert_eq!(c.remaining(), 1);
assert_eq!(c.remaining_mut(), 2);
unsafe {
c.advance_mut(1);
}
assert_eq!(c.remaining(), 2);
assert_eq!(c.remaining_mut(), 1);

assert_eq!(<CircBuf as Buf>::chunk(&c).len(), 2);
assert_eq!(c.chunk_mut().len(), 1);

let mut dst = [IoSlice::new(&[]); 2];
assert_eq!(c.chunks_vectored(&mut dst[..]), 2);

assert_eq!(dst[0].len(), 2);
assert_eq!(dst[1].len(), 0);
}

#[test]
fn bytes_buf_remaining() {
use bytes::{Buf, BufMut};

let mut c = CircBuf::with_capacity(4).unwrap();

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
assert!(!c.has_remaining());
assert!(c.has_remaining_mut());

unsafe {
c.advance_mut(3);
}

assert_eq!(c.remaining(), 3);
assert_eq!(c.remaining_mut(), 0);
assert!(c.has_remaining());
assert!(!c.has_remaining_mut());

c.advance(2);

assert_eq!(c.remaining(), 1);
assert_eq!(c.remaining_mut(), 2);
assert!(c.has_remaining());
assert!(c.has_remaining_mut());

c.advance(1);

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
assert!(!c.has_remaining());
assert!(c.has_remaining_mut());
}

#[cfg(feature = "bytes")]
#[test]
fn bytes_bufmut_hello() {
use bytes::BufMut;

let mut c = CircBuf::with_capacity(16).unwrap();

unsafe {
c.chunk_mut().write_byte(0, b'h');
c.chunk_mut().write_byte(1, b'e');

c.advance_mut(2);

c.chunk_mut().write_byte(0, b'l');
c.chunk_mut().write_byte(1, b'l');
c.chunk_mut().write_byte(2, b'o');

c.advance_mut(3);
}

assert_eq!(c.get_bytes()[0], b"hello");
}
}
183 changes: 3 additions & 180 deletions src/lib.rs
Expand Up @@ -114,6 +114,9 @@
//! }
//! ```

#[cfg(feature = "bytes")]
mod bytes;

use std::boxed::Box;
use std::error;
use std::fmt;
Expand Down Expand Up @@ -547,82 +550,6 @@ impl io::Write for CircBuf {
}
}

#[cfg(feature = "bytes")]
impl bytes::Buf for CircBuf {
fn remaining(&self) -> usize {
self.len()
}

fn advance(&mut self, count: usize) {
assert!(count == 0 || count <= self.remaining());
self.advance_read(count);
}

fn bytes(&self) -> &[u8] {
let [left, right] = self.get_bytes();
match (left.is_empty(), right.is_empty()) {
(true, true) => left,
(true, false) => right,
(false, true) => left,
(false, false) => left,
}
}

fn bytes_vectored<'a>(&'a self, dst: &mut [io::IoSlice<'a>]) -> usize {
let [left, right] = self.get_bytes();
let mut count = 0;
if let Some(slice) = dst.get_mut(0) {
count += 1;
*slice = io::IoSlice::new(left);
}
if let Some(slice) = dst.get_mut(1) {
count += 1;
*slice = io::IoSlice::new(right);
}
count
}
}

#[cfg(feature = "bytes")]
impl bytes::BufMut for CircBuf {
fn remaining_mut(&self) -> usize {
self.avail()
}

unsafe fn advance_mut(&mut self, count: usize) {
assert!(count == 0 || count <= self.remaining_mut());
self.advance_write(count);
}

fn bytes_mut<'this>(&'this mut self) -> &'this mut [std::mem::MaybeUninit<u8>] {
let [left, right] = self.get_avail();
let slice = match (left.is_empty(), right.is_empty()) {
(true, true) => left,
(true, false) => right,
(false, true) => left,
(false, false) => left,
};
// As far as I can tell it is perfectly safe to convert from u8 to MaybeUninit<u8>.
unsafe {
std::mem::transmute::<&'this mut [u8], &'this mut [std::mem::MaybeUninit<u8>]>(slice)
}
}

fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [bytes::buf::IoSliceMut<'a>]) -> usize {
let [left, right] = self.get_avail();
let mut count = 0;
if let Some(slice) = dst.get_mut(0) {
count += 1;
*slice = bytes::buf::IoSliceMut::from(left);
}
if let Some(slice) = dst.get_mut(1) {
count += 1;
*slice = bytes::buf::IoSliceMut::from(right);
}
count
}
}

#[cfg(test)]
mod tests {
use super::{CircBuf, CircBufError, DEFAULT_CAPACITY};
Expand Down Expand Up @@ -932,108 +859,4 @@ mod tests {
assert_eq!(c.read_to_string(&mut s).unwrap(), 8);
assert_eq!(s, "fizzbuzz");
}

#[cfg(feature = "bytes")]
#[test]
fn bytes_buf_and_bufmut() {
use bytes::{Buf, BufMut};

let mut c = CircBuf::with_capacity(4).unwrap();

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
unsafe {
c.advance_mut(2);
}
assert_eq!(c.remaining(), 2);
assert_eq!(c.remaining_mut(), 1);
c.advance(1);
assert_eq!(c.remaining(), 1);
assert_eq!(c.remaining_mut(), 2);
unsafe {
c.advance_mut(1);
}
assert_eq!(c.remaining(), 2);
assert_eq!(c.remaining_mut(), 1);

assert_eq!(<CircBuf as Buf>::bytes(&c).len(), 2);
assert_eq!(c.bytes_mut().len(), 1);

let mut dst = [std::io::IoSlice::new(&[]); 2];
assert_eq!(c.bytes_vectored(&mut dst[..]), 2);

assert_eq!(dst[0].len(), 2);
assert_eq!(dst[1].len(), 0);

let b1: &mut [u8] = &mut [];
let b2: &mut [u8] = &mut [];
let mut dst_mut = [
bytes::buf::IoSliceMut::from(b1),
bytes::buf::IoSliceMut::from(b2),
];

assert_eq!(c.bytes_vectored_mut(&mut dst_mut[..]), 2);

assert!(c.has_remaining());
assert!(c.has_remaining_mut());
}

#[cfg(feature = "bytes")]
#[test]
fn bytes_buf_remaining() {
use bytes::{Buf, BufMut};

let mut c = CircBuf::with_capacity(4).unwrap();

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
assert!(!c.has_remaining());
assert!(c.has_remaining_mut());

unsafe {
c.advance_mut(3);
}

assert_eq!(c.remaining(), 3);
assert_eq!(c.remaining_mut(), 0);
assert!(c.has_remaining());
assert!(!c.has_remaining_mut());

c.advance(2);

assert_eq!(c.remaining(), 1);
assert_eq!(c.remaining_mut(), 2);
assert!(c.has_remaining());
assert!(c.has_remaining_mut());

c.advance(1);

assert_eq!(c.remaining(), 0);
assert_eq!(c.remaining_mut(), 3);
assert!(!c.has_remaining());
assert!(c.has_remaining_mut());
}

#[cfg(feature = "bytes")]
#[test]
fn bytes_bufmut_hello() {
use bytes::BufMut;

let mut c = CircBuf::with_capacity(16).unwrap();

unsafe {
c.bytes_mut()[0].as_mut_ptr().write(b'h');
c.bytes_mut()[1].as_mut_ptr().write(b'e');

c.advance_mut(2);

c.bytes_mut()[0].as_mut_ptr().write(b'l');
c.bytes_mut()[1].as_mut_ptr().write(b'l');
c.bytes_mut()[2].as_mut_ptr().write(b'o');

c.advance_mut(3);
}

assert_eq!(c.get_bytes()[0], b"hello");
}
}