mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-26 00:00:20 +02:00
This lets us take Bytes and a &[u8] slice that is contained in it, and create a new Bytes that corresponds to that subset slice. Closes #198
This commit is contained in:
committed by
Carl Lerche
parent
ed244d3b54
commit
79f05591c9
@@ -576,6 +576,46 @@ impl Bytes {
|
|||||||
self.slice(0, end)
|
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
|
||||||
|
/// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it.
|
||||||
|
/// This function turns that `&[u8]` into another `Bytes`, as if one had
|
||||||
|
/// called `self.slice()` with the offsets that correspond to `subset`.
|
||||||
|
///
|
||||||
|
/// This operation is `O(1)`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use bytes::Bytes;
|
||||||
|
///
|
||||||
|
/// let bytes = Bytes::from(&b"012345678"[..]);
|
||||||
|
/// let as_slice = bytes.as_ref();
|
||||||
|
/// let subset = &as_slice[2..6];
|
||||||
|
/// let subslice = bytes.slice_ref(&subset);
|
||||||
|
/// assert_eq!(&subslice[..], b"2345");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Requires that the given `sub` slice is in fact contained within the
|
||||||
|
/// `Bytes` buffer; otherwise this function will panic.
|
||||||
|
pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
|
||||||
|
let bytes_p = self.as_ptr() as usize;
|
||||||
|
let bytes_len = self.len();
|
||||||
|
|
||||||
|
let sub_p = subset.as_ptr() as usize;
|
||||||
|
let sub_len = subset.len();
|
||||||
|
|
||||||
|
assert!(sub_p >= bytes_p);
|
||||||
|
assert!(sub_p + sub_len <= bytes_p + bytes_len);
|
||||||
|
|
||||||
|
let sub_offset = sub_p - bytes_p;
|
||||||
|
|
||||||
|
self.slice(sub_offset, sub_offset + sub_len)
|
||||||
|
}
|
||||||
|
|
||||||
/// Splits the bytes into two at the given index.
|
/// Splits the bytes into two at the given index.
|
||||||
///
|
///
|
||||||
/// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
|
/// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
|
||||||
|
|||||||
@@ -717,3 +717,57 @@ fn from_iter_no_size_hint() {
|
|||||||
|
|
||||||
assert_eq!(&actual[..], &expect[..]);
|
assert_eq!(&actual[..], &expect[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_slice_ref(bytes: &Bytes, start: usize, end: usize, expected: &[u8]) {
|
||||||
|
let slice = &(bytes.as_ref()[start..end]);
|
||||||
|
let sub = bytes.slice_ref(&slice);
|
||||||
|
assert_eq!(&sub[..], expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn slice_ref_works() {
|
||||||
|
let bytes = Bytes::from(&b"012345678"[..]);
|
||||||
|
|
||||||
|
test_slice_ref(&bytes, 0, 0, b"");
|
||||||
|
test_slice_ref(&bytes, 0, 3, b"012");
|
||||||
|
test_slice_ref(&bytes, 2, 6, b"2345");
|
||||||
|
test_slice_ref(&bytes, 7, 9, b"78");
|
||||||
|
test_slice_ref(&bytes, 9, 9, b"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn slice_ref_empty() {
|
||||||
|
let bytes = Bytes::from(&b""[..]);
|
||||||
|
let slice = &(bytes.as_ref()[0..0]);
|
||||||
|
|
||||||
|
let sub = bytes.slice_ref(&slice);
|
||||||
|
assert_eq!(&sub[..], b"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn slice_ref_catches_not_a_subset() {
|
||||||
|
let bytes = Bytes::from(&b"012345678"[..]);
|
||||||
|
let slice = &b"012345"[0..4];
|
||||||
|
|
||||||
|
bytes.slice_ref(slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn slice_ref_catches_not_an_empty_subset() {
|
||||||
|
let bytes = Bytes::from(&b"012345678"[..]);
|
||||||
|
let slice = &b""[0..0];
|
||||||
|
|
||||||
|
bytes.slice_ref(slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn empty_slice_ref_catches_not_an_empty_subset() {
|
||||||
|
let bytes = Bytes::from(&b""[..]);
|
||||||
|
let slice = &b""[0..0];
|
||||||
|
|
||||||
|
bytes.slice_ref(slice);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user