| #![warn(rust_2018_idioms)] | |
| use bytes::{Buf, BufMut, Bytes, BytesMut}; | |
| use std::usize; | |
| const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb"; | |
| const SHORT: &'static [u8] = b"hello world"; | |
| fn is_sync<T: Sync>() {} | |
| fn is_send<T: Send>() {} | |
| #[test] | |
| fn test_bounds() { | |
| is_sync::<Bytes>(); | |
| is_sync::<BytesMut>(); | |
| is_send::<Bytes>(); | |
| is_send::<BytesMut>(); | |
| } | |
| #[test] | |
| fn test_layout() { | |
| use std::mem; | |
| assert_eq!( | |
| mem::size_of::<Bytes>(), | |
| mem::size_of::<usize>() * 4, | |
| "Bytes size should be 4 words", | |
| ); | |
| assert_eq!( | |
| mem::size_of::<BytesMut>(), | |
| mem::size_of::<usize>() * 4, | |
| "BytesMut should be 4 words", | |
| ); | |
| assert_eq!( | |
| mem::size_of::<Bytes>(), | |
| mem::size_of::<Option<Bytes>>(), | |
| "Bytes should be same size as Option<Bytes>", | |
| ); | |
| assert_eq!( | |
| mem::size_of::<BytesMut>(), | |
| mem::size_of::<Option<BytesMut>>(), | |
| "BytesMut should be same size as Option<BytesMut>", | |
| ); | |
| } | |
| #[test] | |
| fn from_slice() { | |
| let a = Bytes::from(&b"abcdefgh"[..]); | |
| assert_eq!(a, b"abcdefgh"[..]); | |
| assert_eq!(a, &b"abcdefgh"[..]); | |
| assert_eq!(a, Vec::from(&b"abcdefgh"[..])); | |
| assert_eq!(b"abcdefgh"[..], a); | |
| assert_eq!(&b"abcdefgh"[..], a); | |
| assert_eq!(Vec::from(&b"abcdefgh"[..]), a); | |
| let a = BytesMut::from(&b"abcdefgh"[..]); | |
| assert_eq!(a, b"abcdefgh"[..]); | |
| assert_eq!(a, &b"abcdefgh"[..]); | |
| assert_eq!(a, Vec::from(&b"abcdefgh"[..])); | |
| assert_eq!(b"abcdefgh"[..], a); | |
| assert_eq!(&b"abcdefgh"[..], a); | |
| assert_eq!(Vec::from(&b"abcdefgh"[..]), a); | |
| } | |
| #[test] | |
| fn fmt() { | |
| let a = format!("{:?}", Bytes::from(&b"abcdefg"[..])); | |
| let b = "b\"abcdefg\""; | |
| assert_eq!(a, b); | |
| let a = format!("{:?}", BytesMut::from(&b"abcdefg"[..])); | |
| assert_eq!(a, b); | |
| } | |
| #[test] | |
| fn fmt_write() { | |
| use std::fmt::Write; | |
| use std::iter::FromIterator; | |
| let s = String::from_iter((0..10).map(|_| "abcdefg")); | |
| let mut a = BytesMut::with_capacity(64); | |
| write!(a, "{}", &s[..64]).unwrap(); | |
| assert_eq!(a, s[..64].as_bytes()); | |
| let mut b = BytesMut::with_capacity(64); | |
| write!(b, "{}", &s[..32]).unwrap(); | |
| write!(b, "{}", &s[32..64]).unwrap(); | |
| assert_eq!(b, s[..64].as_bytes()); | |
| let mut c = BytesMut::with_capacity(64); | |
| write!(c, "{}", s).unwrap(); | |
| assert_eq!(c, s[..].as_bytes()); | |
| } | |
| #[test] | |
| fn len() { | |
| let a = Bytes::from(&b"abcdefg"[..]); | |
| assert_eq!(a.len(), 7); | |
| let a = BytesMut::from(&b"abcdefg"[..]); | |
| assert_eq!(a.len(), 7); | |
| let a = Bytes::from(&b""[..]); | |
| assert!(a.is_empty()); | |
| let a = BytesMut::from(&b""[..]); | |
| assert!(a.is_empty()); | |
| } | |
| #[test] | |
| fn index() { | |
| let a = Bytes::from(&b"hello world"[..]); | |
| assert_eq!(a[0..5], *b"hello"); | |
| } | |
| #[test] | |
| fn slice() { | |
| let a = Bytes::from(&b"hello world"[..]); | |
| let b = a.slice(3..5); | |
| assert_eq!(b, b"lo"[..]); | |
| let b = a.slice(0..0); | |
| assert_eq!(b, b""[..]); | |
| let b = a.slice(3..3); | |
| assert_eq!(b, b""[..]); | |
| let b = a.slice(a.len()..a.len()); | |
| assert_eq!(b, b""[..]); | |
| let b = a.slice(..5); | |
| assert_eq!(b, b"hello"[..]); | |
| 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..44); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn slice_oob_2() { | |
| let a = Bytes::from(&b"hello world"[..]); | |
| a.slice(44..49); | |
| } | |
| #[test] | |
| fn split_off() { | |
| let mut hello = Bytes::from(&b"helloworld"[..]); | |
| let world = hello.split_off(5); | |
| assert_eq!(hello, &b"hello"[..]); | |
| assert_eq!(world, &b"world"[..]); | |
| let mut hello = BytesMut::from(&b"helloworld"[..]); | |
| let world = hello.split_off(5); | |
| assert_eq!(hello, &b"hello"[..]); | |
| assert_eq!(world, &b"world"[..]); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn split_off_oob() { | |
| let mut hello = Bytes::from(&b"helloworld"[..]); | |
| let _ = hello.split_off(44); | |
| } | |
| #[test] | |
| fn split_off_uninitialized() { | |
| let mut bytes = BytesMut::with_capacity(1024); | |
| let other = bytes.split_off(128); | |
| assert_eq!(bytes.len(), 0); | |
| assert_eq!(bytes.capacity(), 128); | |
| assert_eq!(other.len(), 0); | |
| assert_eq!(other.capacity(), 896); | |
| } | |
| #[test] | |
| fn split_off_to_loop() { | |
| let s = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
| for i in 0..(s.len() + 1) { | |
| { | |
| let mut bytes = Bytes::from(&s[..]); | |
| let off = bytes.split_off(i); | |
| assert_eq!(i, bytes.len()); | |
| let mut sum = Vec::new(); | |
| sum.extend(bytes.iter()); | |
| sum.extend(off.iter()); | |
| assert_eq!(&s[..], &sum[..]); | |
| } | |
| { | |
| let mut bytes = BytesMut::from(&s[..]); | |
| let off = bytes.split_off(i); | |
| assert_eq!(i, bytes.len()); | |
| let mut sum = Vec::new(); | |
| sum.extend(&bytes); | |
| sum.extend(&off); | |
| assert_eq!(&s[..], &sum[..]); | |
| } | |
| { | |
| let mut bytes = Bytes::from(&s[..]); | |
| let off = bytes.split_to(i); | |
| assert_eq!(i, off.len()); | |
| let mut sum = Vec::new(); | |
| sum.extend(off.iter()); | |
| sum.extend(bytes.iter()); | |
| assert_eq!(&s[..], &sum[..]); | |
| } | |
| { | |
| let mut bytes = BytesMut::from(&s[..]); | |
| let off = bytes.split_to(i); | |
| assert_eq!(i, off.len()); | |
| let mut sum = Vec::new(); | |
| sum.extend(&off); | |
| sum.extend(&bytes); | |
| assert_eq!(&s[..], &sum[..]); | |
| } | |
| } | |
| } | |
| #[test] | |
| fn split_to_1() { | |
| // Static | |
| let mut a = Bytes::from_static(SHORT); | |
| let b = a.split_to(4); | |
| assert_eq!(SHORT[4..], a); | |
| assert_eq!(SHORT[..4], b); | |
| // Allocated | |
| let mut a = Bytes::copy_from_slice(LONG); | |
| let b = a.split_to(4); | |
| assert_eq!(LONG[4..], a); | |
| assert_eq!(LONG[..4], b); | |
| let mut a = Bytes::copy_from_slice(LONG); | |
| let b = a.split_to(30); | |
| assert_eq!(LONG[30..], a); | |
| assert_eq!(LONG[..30], b); | |
| } | |
| #[test] | |
| fn split_to_2() { | |
| let mut a = Bytes::from(LONG); | |
| assert_eq!(LONG, a); | |
| let b = a.split_to(1); | |
| assert_eq!(LONG[1..], a); | |
| drop(b); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn split_to_oob() { | |
| let mut hello = Bytes::from(&b"helloworld"[..]); | |
| let _ = hello.split_to(33); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn split_to_oob_mut() { | |
| let mut hello = BytesMut::from(&b"helloworld"[..]); | |
| let _ = hello.split_to(33); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn split_to_uninitialized() { | |
| let mut bytes = BytesMut::with_capacity(1024); | |
| let _other = bytes.split_to(128); | |
| } | |
| #[test] | |
| fn split_off_to_at_gt_len() { | |
| fn make_bytes() -> Bytes { | |
| let mut bytes = BytesMut::with_capacity(100); | |
| bytes.put_slice(&[10, 20, 30, 40]); | |
| bytes.freeze() | |
| } | |
| use std::panic; | |
| let _ = make_bytes().split_to(4); | |
| let _ = make_bytes().split_off(4); | |
| assert!(panic::catch_unwind(move || { | |
| let _ = make_bytes().split_to(5); | |
| }) | |
| .is_err()); | |
| assert!(panic::catch_unwind(move || { | |
| let _ = make_bytes().split_off(5); | |
| }) | |
| .is_err()); | |
| } | |
| #[test] | |
| fn truncate() { | |
| let s = &b"helloworld"[..]; | |
| let mut hello = Bytes::from(s); | |
| hello.truncate(15); | |
| assert_eq!(hello, s); | |
| hello.truncate(10); | |
| assert_eq!(hello, s); | |
| hello.truncate(5); | |
| assert_eq!(hello, "hello"); | |
| } | |
| #[test] | |
| fn freeze_clone_shared() { | |
| let s = &b"abcdefgh"[..]; | |
| let b = BytesMut::from(s).split().freeze(); | |
| assert_eq!(b, s); | |
| let c = b.clone(); | |
| assert_eq!(c, s); | |
| } | |
| #[test] | |
| fn freeze_clone_unique() { | |
| let s = &b"abcdefgh"[..]; | |
| let b = BytesMut::from(s).freeze(); | |
| assert_eq!(b, s); | |
| let c = b.clone(); | |
| assert_eq!(c, s); | |
| } | |
| #[test] | |
| fn freeze_after_advance() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| b.advance(1); | |
| assert_eq!(b, s[1..]); | |
| let b = b.freeze(); | |
| // Verify fix for #352. Previously, freeze would ignore the start offset | |
| // for BytesMuts in Vec mode. | |
| assert_eq!(b, s[1..]); | |
| } | |
| #[test] | |
| fn freeze_after_advance_arc() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| // Make b Arc | |
| let _ = b.split_to(0); | |
| b.advance(1); | |
| assert_eq!(b, s[1..]); | |
| let b = b.freeze(); | |
| assert_eq!(b, s[1..]); | |
| } | |
| #[test] | |
| fn freeze_after_split_to() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| let _ = b.split_to(1); | |
| assert_eq!(b, s[1..]); | |
| let b = b.freeze(); | |
| assert_eq!(b, s[1..]); | |
| } | |
| #[test] | |
| fn freeze_after_truncate() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| b.truncate(7); | |
| assert_eq!(b, s[..7]); | |
| let b = b.freeze(); | |
| assert_eq!(b, s[..7]); | |
| } | |
| #[test] | |
| fn freeze_after_truncate_arc() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| // Make b Arc | |
| let _ = b.split_to(0); | |
| b.truncate(7); | |
| assert_eq!(b, s[..7]); | |
| let b = b.freeze(); | |
| assert_eq!(b, s[..7]); | |
| } | |
| #[test] | |
| fn freeze_after_split_off() { | |
| let s = &b"abcdefgh"[..]; | |
| let mut b = BytesMut::from(s); | |
| let _ = b.split_off(7); | |
| assert_eq!(b, s[..7]); | |
| let b = b.freeze(); | |
| assert_eq!(b, s[..7]); | |
| } | |
| #[test] | |
| fn fns_defined_for_bytes_mut() { | |
| let mut bytes = BytesMut::from(&b"hello world"[..]); | |
| bytes.as_ptr(); | |
| bytes.as_mut_ptr(); | |
| // Iterator | |
| let v: Vec<u8> = bytes.as_ref().iter().cloned().collect(); | |
| assert_eq!(&v[..], bytes); | |
| } | |
| #[test] | |
| fn reserve_convert() { | |
| // Vec -> Vec | |
| let mut bytes = BytesMut::from(LONG); | |
| bytes.reserve(64); | |
| assert_eq!(bytes.capacity(), LONG.len() + 64); | |
| // Arc -> Vec | |
| let mut bytes = BytesMut::from(LONG); | |
| let a = bytes.split_to(30); | |
| bytes.reserve(128); | |
| assert!(bytes.capacity() >= bytes.len() + 128); | |
| drop(a); | |
| } | |
| #[test] | |
| fn reserve_growth() { | |
| let mut bytes = BytesMut::with_capacity(64); | |
| bytes.put("hello world".as_bytes()); | |
| let _ = bytes.split(); | |
| bytes.reserve(65); | |
| assert_eq!(bytes.capacity(), 128); | |
| } | |
| #[test] | |
| fn reserve_allocates_at_least_original_capacity() { | |
| let mut bytes = BytesMut::with_capacity(1024); | |
| for i in 0..1020 { | |
| bytes.put_u8(i as u8); | |
| } | |
| let _other = bytes.split(); | |
| bytes.reserve(16); | |
| assert_eq!(bytes.capacity(), 1024); | |
| } | |
| #[test] | |
| #[cfg_attr(miri, ignore)] // Miri is too slow | |
| fn reserve_max_original_capacity_value() { | |
| const SIZE: usize = 128 * 1024; | |
| let mut bytes = BytesMut::with_capacity(SIZE); | |
| for _ in 0..SIZE { | |
| bytes.put_u8(0u8); | |
| } | |
| let _other = bytes.split(); | |
| bytes.reserve(16); | |
| assert_eq!(bytes.capacity(), 64 * 1024); | |
| } | |
| #[test] | |
| fn reserve_vec_recycling() { | |
| let mut bytes = BytesMut::with_capacity(16); | |
| assert_eq!(bytes.capacity(), 16); | |
| let addr = bytes.as_ptr() as usize; | |
| bytes.put("0123456789012345".as_bytes()); | |
| assert_eq!(bytes.as_ptr() as usize, addr); | |
| bytes.advance(10); | |
| assert_eq!(bytes.capacity(), 6); | |
| bytes.reserve(8); | |
| assert_eq!(bytes.capacity(), 16); | |
| assert_eq!(bytes.as_ptr() as usize, addr); | |
| } | |
| #[test] | |
| fn reserve_in_arc_unique_does_not_overallocate() { | |
| let mut bytes = BytesMut::with_capacity(1000); | |
| let _ = bytes.split(); | |
| // now bytes is Arc and refcount == 1 | |
| assert_eq!(1000, bytes.capacity()); | |
| bytes.reserve(2001); | |
| assert_eq!(2001, bytes.capacity()); | |
| } | |
| #[test] | |
| fn reserve_in_arc_unique_doubles() { | |
| let mut bytes = BytesMut::with_capacity(1000); | |
| let _ = bytes.split(); | |
| // now bytes is Arc and refcount == 1 | |
| assert_eq!(1000, bytes.capacity()); | |
| bytes.reserve(1001); | |
| assert_eq!(2000, bytes.capacity()); | |
| } | |
| #[test] | |
| fn reserve_in_arc_nonunique_does_not_overallocate() { | |
| let mut bytes = BytesMut::with_capacity(1000); | |
| let _copy = bytes.split(); | |
| // now bytes is Arc and refcount == 2 | |
| assert_eq!(1000, bytes.capacity()); | |
| bytes.reserve(2001); | |
| assert_eq!(2001, bytes.capacity()); | |
| } | |
| #[test] | |
| fn extend_mut() { | |
| let mut bytes = BytesMut::with_capacity(0); | |
| bytes.extend(LONG); | |
| assert_eq!(*bytes, LONG[..]); | |
| } | |
| #[test] | |
| fn extend_from_slice_mut() { | |
| for &i in &[3, 34] { | |
| let mut bytes = BytesMut::new(); | |
| bytes.extend_from_slice(&LONG[..i]); | |
| bytes.extend_from_slice(&LONG[i..]); | |
| assert_eq!(LONG[..], *bytes); | |
| } | |
| } | |
| #[test] | |
| fn extend_mut_without_size_hint() { | |
| let mut bytes = BytesMut::with_capacity(0); | |
| let mut long_iter = LONG.iter(); | |
| // Use iter::from_fn since it doesn't know a size_hint | |
| bytes.extend(std::iter::from_fn(|| long_iter.next())); | |
| assert_eq!(*bytes, LONG[..]); | |
| } | |
| #[test] | |
| fn from_static() { | |
| let mut a = Bytes::from_static(b"ab"); | |
| let b = a.split_off(1); | |
| assert_eq!(a, b"a"[..]); | |
| assert_eq!(b, b"b"[..]); | |
| } | |
| #[test] | |
| fn advance_static() { | |
| let mut a = Bytes::from_static(b"hello world"); | |
| a.advance(6); | |
| assert_eq!(a, &b"world"[..]); | |
| } | |
| #[test] | |
| fn advance_vec() { | |
| let mut a = Bytes::from(b"hello world boooo yah world zomg wat wat".to_vec()); | |
| a.advance(16); | |
| assert_eq!(a, b"o yah world zomg wat wat"[..]); | |
| a.advance(4); | |
| assert_eq!(a, b"h world zomg wat wat"[..]); | |
| a.advance(6); | |
| assert_eq!(a, b"d zomg wat wat"[..]); | |
| } | |
| #[test] | |
| fn advance_bytes_mut() { | |
| let mut a = BytesMut::from("hello world boooo yah world zomg wat wat"); | |
| a.advance(16); | |
| assert_eq!(a, b"o yah world zomg wat wat"[..]); | |
| a.advance(4); | |
| assert_eq!(a, b"h world zomg wat wat"[..]); | |
| // Reserve some space. | |
| a.reserve(1024); | |
| assert_eq!(a, b"h world zomg wat wat"[..]); | |
| a.advance(6); | |
| assert_eq!(a, b"d zomg wat wat"[..]); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn advance_past_len() { | |
| let mut a = BytesMut::from("hello world"); | |
| a.advance(20); | |
| } | |
| #[test] | |
| // Only run these tests on little endian systems. CI uses qemu for testing | |
| // big endian... and qemu doesn't really support threading all that well. | |
| #[cfg(any(miri, target_endian = "little"))] | |
| fn stress() { | |
| // Tests promoting a buffer from a vec -> shared in a concurrent situation | |
| use std::sync::{Arc, Barrier}; | |
| use std::thread; | |
| const THREADS: usize = 8; | |
| const ITERS: usize = if cfg!(miri) { 100 } else { 1_000 }; | |
| for i in 0..ITERS { | |
| let data = [i as u8; 256]; | |
| let buf = Arc::new(Bytes::copy_from_slice(&data[..])); | |
| let barrier = Arc::new(Barrier::new(THREADS)); | |
| let mut joins = Vec::with_capacity(THREADS); | |
| for _ in 0..THREADS { | |
| let c = barrier.clone(); | |
| let buf = buf.clone(); | |
| joins.push(thread::spawn(move || { | |
| c.wait(); | |
| let buf: Bytes = (*buf).clone(); | |
| drop(buf); | |
| })); | |
| } | |
| for th in joins { | |
| th.join().unwrap(); | |
| } | |
| assert_eq!(*buf, data[..]); | |
| } | |
| } | |
| #[test] | |
| fn partial_eq_bytesmut() { | |
| let bytes = Bytes::from(&b"The quick red fox"[..]); | |
| let bytesmut = BytesMut::from(&b"The quick red fox"[..]); | |
| assert!(bytes == bytesmut); | |
| assert!(bytesmut == bytes); | |
| let bytes2 = Bytes::from(&b"Jumped over the lazy brown dog"[..]); | |
| assert!(bytes2 != bytesmut); | |
| assert!(bytesmut != bytes2); | |
| } | |
| /* | |
| #[test] | |
| fn bytes_unsplit_basic() { | |
| let buf = Bytes::from(&b"aaabbbcccddd"[..]); | |
| let splitted = buf.split_off(6); | |
| assert_eq!(b"aaabbb", &buf[..]); | |
| assert_eq!(b"cccddd", &splitted[..]); | |
| buf.unsplit(splitted); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_unsplit_empty_other() { | |
| let buf = Bytes::from(&b"aaabbbcccddd"[..]); | |
| // empty other | |
| let other = Bytes::new(); | |
| buf.unsplit(other); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_unsplit_empty_self() { | |
| // empty self | |
| let mut buf = Bytes::new(); | |
| let mut other = Bytes::with_capacity(64); | |
| other.extend_from_slice(b"aaabbbcccddd"); | |
| buf.unsplit(other); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_unsplit_arc_different() { | |
| let mut buf = Bytes::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbeeee"); | |
| buf.split_off(8); //arc | |
| let mut buf2 = Bytes::with_capacity(64); | |
| buf2.extend_from_slice(b"ccccddddeeee"); | |
| buf2.split_off(8); //arc | |
| buf.unsplit(buf2); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_unsplit_arc_non_contiguous() { | |
| let mut buf = Bytes::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbeeeeccccdddd"); | |
| let mut buf2 = buf.split_off(8); //arc | |
| let buf3 = buf2.split_off(4); //arc | |
| buf.unsplit(buf3); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_unsplit_two_split_offs() { | |
| let mut buf = Bytes::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbccccdddd"); | |
| let mut buf2 = buf.split_off(8); //arc | |
| let buf3 = buf2.split_off(4); //arc | |
| buf2.unsplit(buf3); | |
| buf.unsplit(buf2); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| 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); | |
| buf0010.unsplit(buf1020); | |
| assert_eq!(b"abcdefghijklmnopqrst", &buf0010[..]); | |
| assert_eq!(b"fghijklmno", &buf0515[..]); | |
| } | |
| */ | |
| #[test] | |
| fn bytes_mut_unsplit_basic() { | |
| let mut buf = BytesMut::with_capacity(64); | |
| buf.extend_from_slice(b"aaabbbcccddd"); | |
| let splitted = buf.split_off(6); | |
| assert_eq!(b"aaabbb", &buf[..]); | |
| assert_eq!(b"cccddd", &splitted[..]); | |
| buf.unsplit(splitted); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_mut_unsplit_empty_other() { | |
| let mut buf = BytesMut::with_capacity(64); | |
| buf.extend_from_slice(b"aaabbbcccddd"); | |
| // empty other | |
| let other = BytesMut::new(); | |
| buf.unsplit(other); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_mut_unsplit_empty_self() { | |
| // empty self | |
| let mut buf = BytesMut::new(); | |
| let mut other = BytesMut::with_capacity(64); | |
| other.extend_from_slice(b"aaabbbcccddd"); | |
| buf.unsplit(other); | |
| assert_eq!(b"aaabbbcccddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_mut_unsplit_arc_different() { | |
| let mut buf = BytesMut::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbeeee"); | |
| let _ = buf.split_off(8); //arc | |
| let mut buf2 = BytesMut::with_capacity(64); | |
| buf2.extend_from_slice(b"ccccddddeeee"); | |
| let _ = buf2.split_off(8); //arc | |
| buf.unsplit(buf2); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_mut_unsplit_arc_non_contiguous() { | |
| let mut buf = BytesMut::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbeeeeccccdddd"); | |
| let mut buf2 = buf.split_off(8); //arc | |
| let buf3 = buf2.split_off(4); //arc | |
| buf.unsplit(buf3); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| fn bytes_mut_unsplit_two_split_offs() { | |
| let mut buf = BytesMut::with_capacity(64); | |
| buf.extend_from_slice(b"aaaabbbbccccdddd"); | |
| let mut buf2 = buf.split_off(8); //arc | |
| let buf3 = buf2.split_off(4); //arc | |
| buf2.unsplit(buf3); | |
| buf.unsplit(buf2); | |
| assert_eq!(b"aaaabbbbccccdddd", &buf[..]); | |
| } | |
| #[test] | |
| fn from_iter_no_size_hint() { | |
| use std::iter; | |
| let mut expect = vec![]; | |
| let actual: Bytes = iter::repeat(b'x') | |
| .scan(100, |cnt, item| { | |
| if *cnt >= 1 { | |
| *cnt -= 1; | |
| expect.push(item); | |
| Some(item) | |
| } else { | |
| None | |
| } | |
| }) | |
| .collect(); | |
| 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] | |
| fn slice_ref_empty_subslice() { | |
| let bytes = Bytes::from(&b"abcde"[..]); | |
| let subbytes = bytes.slice(0..0); | |
| let slice = &subbytes[..]; | |
| // The `slice` object is derived from the original `bytes` object | |
| // so `slice_ref` should work. | |
| assert_eq!(Bytes::new(), bytes.slice_ref(slice)); | |
| } | |
| #[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] | |
| fn slice_ref_not_an_empty_subset() { | |
| let bytes = Bytes::from(&b"012345678"[..]); | |
| let slice = &b""[0..0]; | |
| assert_eq!(Bytes::new(), bytes.slice_ref(slice)); | |
| } | |
| #[test] | |
| fn empty_slice_ref_not_an_empty_subset() { | |
| let bytes = Bytes::new(); | |
| let slice = &b"some other slice"[0..0]; | |
| assert_eq!(Bytes::new(), bytes.slice_ref(slice)); | |
| } | |
| #[test] | |
| fn bytes_buf_mut_advance() { | |
| let mut bytes = BytesMut::with_capacity(1024); | |
| unsafe { | |
| let ptr = bytes.chunk_mut().as_mut_ptr(); | |
| assert_eq!(1024, bytes.chunk_mut().len()); | |
| bytes.advance_mut(10); | |
| let next = bytes.chunk_mut().as_mut_ptr(); | |
| assert_eq!(1024 - 10, bytes.chunk_mut().len()); | |
| assert_eq!(ptr.offset(10), next); | |
| // advance to the end | |
| bytes.advance_mut(1024 - 10); | |
| // The buffer size is doubled | |
| assert_eq!(1024, bytes.chunk_mut().len()); | |
| } | |
| } | |
| #[test] | |
| fn bytes_buf_mut_reuse_when_fully_consumed() { | |
| use bytes::{Buf, BytesMut}; | |
| let mut buf = BytesMut::new(); | |
| buf.reserve(8192); | |
| buf.extend_from_slice(&[0u8; 100][..]); | |
| let p = &buf[0] as *const u8; | |
| buf.advance(100); | |
| buf.reserve(8192); | |
| buf.extend_from_slice(b" "); | |
| assert_eq!(&buf[0] as *const u8, p); | |
| } | |
| #[test] | |
| #[should_panic] | |
| fn bytes_reserve_overflow() { | |
| let mut bytes = BytesMut::with_capacity(1024); | |
| bytes.put_slice(b"hello world"); | |
| bytes.reserve(usize::MAX); | |
| } | |
| #[test] | |
| fn bytes_with_capacity_but_empty() { | |
| // See https://github.com/tokio-rs/bytes/issues/340 | |
| let vec = Vec::with_capacity(1); | |
| let _ = Bytes::from(vec); | |
| } |