mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-22 00:00:15 +02:00
Flesh out ToBytes, ByteStr::concat, and ByteStr eq
This commit is contained in:
+10
-6
@@ -1,5 +1,5 @@
|
|||||||
use {alloc, Bytes, ByteBuf, ROByteBuf};
|
use {alloc, Bytes, ByteBuf, ROByteBuf, Rope};
|
||||||
use traits::{Buf, MutBuf, MutBufExt, ByteStr};
|
use traits::{Buf, MutBuf, MutBufExt, ByteStr, ToBytes};
|
||||||
use std::{cmp, ops};
|
use std::{cmp, ops};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -53,8 +53,8 @@ impl ByteStr for SeqByteStr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn concat<B: ByteStr>(&self, _other: B) -> Bytes {
|
fn concat<B: ByteStr+'static>(&self, other: &B) -> Bytes {
|
||||||
unimplemented!();
|
Rope::of(self.clone()).concat(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@@ -75,7 +75,9 @@ impl ByteStr for SeqByteStr {
|
|||||||
|
|
||||||
Bytes::of(bytes)
|
Bytes::of(bytes)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToBytes for SeqByteStr {
|
||||||
fn to_bytes(self) -> Bytes {
|
fn to_bytes(self) -> Bytes {
|
||||||
Bytes::of(self)
|
Bytes::of(self)
|
||||||
}
|
}
|
||||||
@@ -159,8 +161,8 @@ impl ByteStr for SmallByteStr {
|
|||||||
SmallByteStrBuf { small: self.clone() }
|
SmallByteStrBuf { small: self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn concat<B: ByteStr>(&self, _other: B) -> Bytes {
|
fn concat<B: ByteStr+'static>(&self, other: &B) -> Bytes {
|
||||||
unimplemented!();
|
Rope::of(self.clone()).concat(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@@ -174,7 +176,9 @@ impl ByteStr for SmallByteStr {
|
|||||||
fn split_at(&self, _mid: usize) -> (Bytes, Bytes) {
|
fn split_at(&self, _mid: usize) -> (Bytes, Bytes) {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToBytes for SmallByteStr {
|
||||||
fn to_bytes(self) -> Bytes {
|
fn to_bytes(self) -> Bytes {
|
||||||
Bytes::of(self)
|
Bytes::of(self)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -1,4 +1,5 @@
|
|||||||
use {Buf, ByteStr, ByteBuf, SmallByteStr};
|
use {ByteBuf, SmallByteStr};
|
||||||
|
use traits::{Buf, ByteStr, ToBytes};
|
||||||
use std::{fmt, mem, ops, ptr};
|
use std::{fmt, mem, ops, ptr};
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
@@ -136,8 +137,8 @@ impl ByteStr for Bytes {
|
|||||||
self.obj().buf()
|
self.obj().buf()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn concat<B: ByteStr+'static>(&self, other: B) -> Bytes {
|
fn concat<B: ByteStr+'static>(&self, other: &B) -> Bytes {
|
||||||
self.obj().concat(Bytes::of(other))
|
self.obj().concat(&Bytes::of(other.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@@ -151,7 +152,9 @@ impl ByteStr for Bytes {
|
|||||||
fn split_at(&self, mid: usize) -> (Bytes, Bytes) {
|
fn split_at(&self, mid: usize) -> (Bytes, Bytes) {
|
||||||
self.obj().split_at(mid)
|
self.obj().split_at(mid)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToBytes for Bytes {
|
||||||
fn to_bytes(self) -> Bytes {
|
fn to_bytes(self) -> Bytes {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -203,7 +206,7 @@ trait ByteStrPriv {
|
|||||||
|
|
||||||
fn clone(&self) -> Bytes;
|
fn clone(&self) -> Bytes;
|
||||||
|
|
||||||
fn concat(&self, other: Bytes) -> Bytes;
|
fn concat(&self, other: &Bytes) -> Bytes;
|
||||||
|
|
||||||
fn drop(&mut self);
|
fn drop(&mut self);
|
||||||
|
|
||||||
@@ -228,7 +231,7 @@ impl<B: ByteStr + 'static> ByteStrPriv for B {
|
|||||||
Bytes::of(self.clone())
|
Bytes::of(self.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn concat(&self, other: Bytes) -> Bytes {
|
fn concat(&self, other: &Bytes) -> Bytes {
|
||||||
self.concat(other)
|
self.concat(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+93
-5
@@ -24,7 +24,7 @@ mod slice;
|
|||||||
|
|
||||||
pub mod traits {
|
pub mod traits {
|
||||||
//! All traits are re-exported here to allow glob imports.
|
//! All traits are re-exported here to allow glob imports.
|
||||||
pub use {Buf, BufExt, MutBuf, MutBufExt, ByteStr};
|
pub use {Buf, BufExt, MutBuf, MutBufExt, ByteStr, ToBytes};
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_CAPACITY: usize = u32::MAX as usize;
|
const MAX_CAPACITY: usize = u32::MAX as usize;
|
||||||
@@ -198,7 +198,7 @@ pub trait MutBufExt {
|
|||||||
/// An immutable sequence of bytes. Operations will not mutate the original
|
/// An immutable sequence of bytes. Operations will not mutate the original
|
||||||
/// value. Since only immutable access is permitted, operations do not require
|
/// value. Since only immutable access is permitted, operations do not require
|
||||||
/// copying (though, sometimes copying will happen as an optimization).
|
/// copying (though, sometimes copying will happen as an optimization).
|
||||||
pub trait ByteStr : Clone + Sized + Send + Sync + ops::Index<usize, Output=u8> {
|
pub trait ByteStr : Clone + Sized + Send + Sync + ToBytes + ops::Index<usize, Output=u8> {
|
||||||
|
|
||||||
// Until HKT lands, the buf must be bound by 'static
|
// Until HKT lands, the buf must be bound by 'static
|
||||||
type Buf: Buf+'static;
|
type Buf: Buf+'static;
|
||||||
@@ -209,7 +209,7 @@ pub trait ByteStr : Clone + Sized + Send + Sync + ops::Index<usize, Output=u8> {
|
|||||||
|
|
||||||
/// Returns a new `Bytes` value representing the concatenation of `self`
|
/// Returns a new `Bytes` value representing the concatenation of `self`
|
||||||
/// with the given `Bytes`.
|
/// with the given `Bytes`.
|
||||||
fn concat<B: ByteStr+'static>(&self, other: B) -> Bytes;
|
fn concat<B: ByteStr+'static>(&self, other: &B) -> Bytes;
|
||||||
|
|
||||||
/// Returns the number of bytes in the ByteStr
|
/// Returns the number of bytes in the ByteStr
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
@@ -249,12 +249,75 @@ pub trait ByteStr : Clone + Sized + Send + Sync + ops::Index<usize, Output=u8> {
|
|||||||
fn split_at(&self, mid: usize) -> (Bytes, Bytes) {
|
fn split_at(&self, mid: usize) -> (Bytes, Bytes) {
|
||||||
(self.slice_to(mid), self.slice_from(mid))
|
(self.slice_to(mid), self.slice_from(mid))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B1: ByteStr, B2: ByteStr> cmp::PartialEq<B2> for B1 {
|
||||||
|
fn eq(&self, other: &B2) -> bool {
|
||||||
|
if self.len() != other.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buf1 = self.buf();
|
||||||
|
let mut buf2 = self.buf();
|
||||||
|
|
||||||
|
while buf1.has_remaining() {
|
||||||
|
let len;
|
||||||
|
|
||||||
|
{
|
||||||
|
let b1 = buf1.bytes();
|
||||||
|
let b2 = buf2.bytes();
|
||||||
|
|
||||||
|
len = cmp::min(b1.len(), b2.len());
|
||||||
|
|
||||||
|
if b1[..len] != b2[..len] {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf1.advance(len);
|
||||||
|
buf2.advance(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ne(&self, other: &B2) -> bool {
|
||||||
|
return !self.eq(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_eq {
|
||||||
|
($ty:ty) => {
|
||||||
|
impl cmp::Eq for $ty {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_eq!(Bytes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ===== ToBytes =====
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub trait ToBytes {
|
||||||
/// Consumes the value and returns a `Bytes` instance containing
|
/// Consumes the value and returns a `Bytes` instance containing
|
||||||
/// identical bytes
|
/// identical bytes
|
||||||
fn to_bytes(self) -> Bytes;
|
fn to_bytes(self) -> Bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ToBytes for &'a [u8] {
|
||||||
|
fn to_bytes(self) -> Bytes {
|
||||||
|
Bytes::from_slice(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToBytes for &'a Vec<u8> {
|
||||||
|
fn to_bytes(self) -> Bytes {
|
||||||
|
self.as_slice().to_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* ===== *Ext impls =====
|
* ===== *Ext impls =====
|
||||||
@@ -351,8 +414,33 @@ impl<'a> Source for &'a Vec<u8> {
|
|||||||
impl<'a> Source for &'a Bytes {
|
impl<'a> Source for &'a Bytes {
|
||||||
type Error = BufError;
|
type Error = BufError;
|
||||||
|
|
||||||
fn fill<B: MutBuf>(self, _buf: &mut B) -> Result<usize, BufError> {
|
fn fill<B: MutBuf>(self, dst: &mut B) -> Result<usize, BufError> {
|
||||||
unimplemented!();
|
let mut src = self.buf();
|
||||||
|
let mut res = 0;
|
||||||
|
|
||||||
|
while src.has_remaining() && dst.has_remaining() {
|
||||||
|
let mut l;
|
||||||
|
|
||||||
|
{
|
||||||
|
let s = src.bytes();
|
||||||
|
let d = dst.mut_bytes();
|
||||||
|
l = cmp::min(s.len(), d.len());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(
|
||||||
|
d.as_mut_ptr(),
|
||||||
|
s.as_ptr(),
|
||||||
|
l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
src.advance(l);
|
||||||
|
dst.advance(l);
|
||||||
|
|
||||||
|
res += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -1,5 +1,5 @@
|
|||||||
use {Bytes, ByteBuf, Source, BufError};
|
use {Bytes, ByteBuf, Source, BufError};
|
||||||
use traits::*;
|
use traits::{Buf, ByteStr, MutBuf, MutBufExt, ToBytes};
|
||||||
use std::{cmp, mem, ops};
|
use std::{cmp, mem, ops};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -98,9 +98,9 @@ impl ByteStr for Rope {
|
|||||||
RopeBuf::new(self.clone())
|
RopeBuf::new(self.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn concat<B: ByteStr+'static>(&self, other: B) -> Bytes {
|
fn concat<B: ByteStr+'static>(&self, other: &B) -> Bytes {
|
||||||
let left = Bytes::of(self.clone());
|
let left = Bytes::of(self.clone());
|
||||||
let right = Bytes::of(other);
|
let right = Bytes::of(other.clone());
|
||||||
Bytes::of(concat(left, right))
|
Bytes::of(concat(left, right))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +146,9 @@ impl ByteStr for Rope {
|
|||||||
|
|
||||||
Bytes::of(Rope::new(left_slice, right_slice))
|
Bytes::of(Rope::new(left_slice, right_slice))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToBytes for Rope {
|
||||||
fn to_bytes(self) -> Bytes {
|
fn to_bytes(self) -> Bytes {
|
||||||
Bytes::of(self)
|
Bytes::of(self)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -69,7 +69,7 @@ pub fn test_rope_concat_two_byte_str() {
|
|||||||
let left = Rope::from_slice(TEST_BYTES_1);
|
let left = Rope::from_slice(TEST_BYTES_1);
|
||||||
let right = Rope::from_slice(TEST_BYTES_2);
|
let right = Rope::from_slice(TEST_BYTES_2);
|
||||||
|
|
||||||
let both = left.concat(right);
|
let both = left.concat(&right);
|
||||||
|
|
||||||
assert_eq!(both.len(), TEST_BYTES_1.len() + TEST_BYTES_2.len());
|
assert_eq!(both.len(), TEST_BYTES_1.len() + TEST_BYTES_2.len());
|
||||||
|
|
||||||
@@ -88,3 +88,17 @@ pub fn test_slice_parity() {
|
|||||||
|
|
||||||
// stuff
|
// stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_rope_equality() {
|
||||||
|
let a = &b"Mary had a little lamb, its fleece was white as snow; ".to_bytes()
|
||||||
|
.concat(&b"And everywhere that Mary went, the lamb was sure to go.".to_bytes());
|
||||||
|
|
||||||
|
let b = &b"Mary had a little lamb, ".to_bytes()
|
||||||
|
.concat(&b"its fleece was white as snow; ".to_bytes())
|
||||||
|
.concat(
|
||||||
|
&b"And everywhere that Mary went, ".to_bytes()
|
||||||
|
.concat(&b"the lamb was sure to go.".to_bytes()));
|
||||||
|
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user