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

Use RangeBounds trait for Bytes::slice #265

Merged
merged 1 commit into from Jun 10, 2019
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
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -19,7 +19,7 @@ matrix:
#
# This job will also build and deploy the docs to gh-pages.
- env: TARGET=x86_64-unknown-linux-gnu
rust: 1.27.0
rust: 1.28.0
after_success:
- |
pip install 'travis-cargo<0.2' --user &&
Expand Down
88 changes: 27 additions & 61 deletions src/bytes.rs
Expand Up @@ -2,8 +2,9 @@ use {Buf, BufMut, IntoBuf};
use buf::IntoIter;
use debug;

use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize};
use std::{cmp, fmt, mem, hash, slice, ptr, usize};
use std::borrow::{Borrow, BorrowMut};
use std::ops::{Deref, DerefMut, RangeBounds};
use std::sync::atomic::{self, AtomicUsize, AtomicPtr};
use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
use std::iter::{FromIterator, Iterator};
Expand All @@ -23,7 +24,7 @@ use std::iter::{FromIterator, Iterator};
/// use bytes::Bytes;
///
/// let mut mem = Bytes::from(&b"Hello world"[..]);
/// let a = mem.slice(0, 5);
/// let a = mem.slice(0..5);
///
/// assert_eq!(&a[..], b"Hello");
///
Expand Down Expand Up @@ -498,7 +499,7 @@ impl Bytes {
self.inner.is_inline()
}

/// Returns a slice of self for the index range `[begin..end)`.
/// Returns a slice of self for the provided range.
///
/// This will increment the reference count for the underlying memory and
/// return a new `Bytes` handle set to the slice.
Expand All @@ -511,7 +512,7 @@ impl Bytes {
/// use bytes::Bytes;
///
/// let a = Bytes::from(&b"hello world"[..]);
/// let b = a.slice(2, 5);
/// let b = a.slice(2..5);
///
/// assert_eq!(&b[..], b"llo");
/// ```
Expand All @@ -520,9 +521,25 @@ impl Bytes {
///
/// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
/// will panic.
pub fn slice(&self, begin: usize, end: usize) -> Bytes {
pub fn slice(&self, range: impl RangeBounds<usize>) -> Bytes {
use std::ops::Bound;

let len = self.len();

let begin = match range.start_bound() {
Bound::Included(&n) => n,
Bound::Excluded(&n) => n + 1,
Bound::Unbounded => 0,
};

let end = match range.end_bound() {
Bound::Included(&n) => n + 1,
Bound::Excluded(&n) => n,
Bound::Unbounded => len,
};

assert!(begin <= end);
assert!(end <= self.len());
assert!(end <= len);

if end - begin <= INLINE_CAP {
return Bytes::from(&self[begin..end]);
Expand All @@ -538,57 +555,6 @@ impl Bytes {
ret
}

/// Returns a slice of self for the index range `[begin..self.len())`.
///
/// This will increment the reference count for the underlying memory and
/// return a new `Bytes` handle set to the slice.
///
/// This operation is `O(1)` and is equivalent to `self.slice(begin,
/// self.len())`.
///
/// # Examples
///
/// ```
/// use bytes::Bytes;
///
/// let a = Bytes::from(&b"hello world"[..]);
/// let b = a.slice_from(6);
///
/// assert_eq!(&b[..], b"world");
/// ```
///
/// # Panics
///
/// Requires that `begin <= self.len()`, otherwise slicing will panic.
pub fn slice_from(&self, begin: usize) -> Bytes {
self.slice(begin, self.len())
}

/// Returns a slice of self for the index range `[0..end)`.
///
/// This will increment the reference count for the underlying memory and
/// return a new `Bytes` handle set to the slice.
///
/// This operation is `O(1)` and is equivalent to `self.slice(0, end)`.
///
/// # Examples
///
/// ```
/// use bytes::Bytes;
///
/// let a = Bytes::from(&b"hello world"[..]);
/// let b = a.slice_to(5);
///
/// assert_eq!(&b[..], b"hello");
/// ```
///
/// # Panics
///
/// Requires that `end <= self.len()`, otherwise slicing will panic.
pub fn slice_to(&self, end: usize) -> Bytes {
self.slice(0, end)
}

/// Returns a slice of self that is equivalent to the given `subset`.
///
/// When processing a `Bytes` buffer with other tools, one often gets a
Expand Down Expand Up @@ -626,7 +592,7 @@ impl Bytes {

let sub_offset = sub_p - bytes_p;

self.slice(sub_offset, sub_offset + sub_len)
self.slice(sub_offset..(sub_offset + sub_len))
}

/// Splits the bytes into two at the given index.
Expand Down Expand Up @@ -924,7 +890,7 @@ impl AsRef<[u8]> for Bytes {
}
}

impl ops::Deref for Bytes {
impl Deref for Bytes {
type Target = [u8];

#[inline]
Expand Down Expand Up @@ -1651,7 +1617,7 @@ impl AsRef<[u8]> for BytesMut {
}
}

impl ops::Deref for BytesMut {
impl Deref for BytesMut {
type Target = [u8];

#[inline]
Expand All @@ -1666,7 +1632,7 @@ impl AsMut<[u8]> for BytesMut {
}
}

impl ops::DerefMut for BytesMut {
impl DerefMut for BytesMut {
#[inline]
fn deref_mut(&mut self) -> &mut [u8] {
self.inner.as_mut()
Expand Down
22 changes: 11 additions & 11 deletions tests/test_bytes.rs
Expand Up @@ -98,37 +98,37 @@ fn index() {
fn slice() {
let a = Bytes::from(&b"hello world"[..]);

let b = a.slice(3, 5);
let b = a.slice(3..5);
assert_eq!(b, b"lo"[..]);

let b = a.slice(0, 0);
let b = a.slice(0..0);
assert_eq!(b, b""[..]);

let b = a.slice(3, 3);
let b = a.slice(3..3);
assert_eq!(b, b""[..]);

let b = a.slice(a.len(), a.len());
let b = a.slice(a.len()..a.len());
assert_eq!(b, b""[..]);

let b = a.slice_to(5);
let b = a.slice(..5);
assert_eq!(b, b"hello"[..]);

let b = a.slice_from(3);
let b = a.slice(3..);
assert_eq!(b, b"lo world"[..]);
}

#[test]
#[should_panic]
fn slice_oob_1() {
let a = Bytes::from(&b"hello world"[..]);
a.slice(5, inline_cap() + 1);
a.slice(5..(inline_cap() + 1));
}

#[test]
#[should_panic]
fn slice_oob_2() {
let a = Bytes::from(&b"hello world"[..]);
a.slice(inline_cap() + 1, inline_cap() + 5);
a.slice((inline_cap() + 1)..(inline_cap() + 5));
}

#[test]
Expand Down Expand Up @@ -689,9 +689,9 @@ fn bytes_unsplit_two_split_offs() {
fn bytes_unsplit_overlapping_references() {
let mut buf = Bytes::with_capacity(64);
buf.extend_from_slice(b"abcdefghijklmnopqrstuvwxyz");
let mut buf0010 = buf.slice(0, 10);
let buf1020 = buf.slice(10, 20);
let buf0515 = buf.slice(5, 15);
let mut buf0010 = buf.slice(0..10);
let buf1020 = buf.slice(10..20);
let buf0515 = buf.slice(5..15);
buf0010.unsplit(buf1020);
assert_eq!(b"abcdefghijklmnopqrst", &buf0010[..]);
assert_eq!(b"fghijklmno", &buf0515[..]);
Expand Down