From ba9a9753583fe10d444fd332d5ac801cbbcc5b78 Mon Sep 17 00:00:00 2001
From: jq-rs <juhamatk@gmail.com>
Date: Sat, 6 Jan 2018 02:20:59 +0200
Subject: [PATCH] Unsplit improvements (#173)

* Handle empty self and other for unsplit.
* Change extend() to extend_from_slice().
---
 src/bytes.rs        | 15 ++++++++++++++-
 tests/test_bytes.rs | 24 ++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/bytes.rs b/src/bytes.rs
index 094d035..f5ac05a 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -295,6 +295,8 @@ pub struct BytesMut {
 #[cfg(target_endian = "little")]
 #[repr(C)]
 struct Inner {
+    // WARNING: Do not access the fields directly unless you know what you are
+    // doing. Instead, use the fns. See implementation comment above.
     arc: AtomicPtr<Shared>,
     ptr: *mut u8,
     len: usize,
@@ -304,6 +306,8 @@ struct Inner {
 #[cfg(target_endian = "big")]
 #[repr(C)]
 struct Inner {
+    // WARNING: Do not access the fields directly unless you know what you are
+    // doing. Instead, use the fns. See implementation comment above.
     ptr: *mut u8,
     len: usize,
     cap: usize,
@@ -1401,6 +1405,15 @@ impl BytesMut {
     pub fn unsplit(&mut self, other: BytesMut) {
         let ptr;
 
+        if other.is_empty() {
+            return;
+        }
+
+        if self.is_empty() {
+            *self = other;
+            return;
+        }
+
         unsafe {
             ptr = self.inner.ptr.offset(self.inner.len as isize); 
         }
@@ -1415,7 +1428,7 @@ impl BytesMut {
             self.inner.cap += other.inner.cap;
         }
         else {
-            self.extend(other);
+            self.extend_from_slice(&other);
         }
     }
 }
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index e5b1fe7..15c3157 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -566,6 +566,30 @@ fn unsplit_basic() {
     assert_eq!(b"aaabbbcccddd", &buf[..]);
 }
 
+#[test]
+fn 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 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 unsplit_inline_arc() {
     let mut buf = BytesMut::with_capacity(8); //inline
-- 
GitLab