diff --git a/src/io/frame.rs b/src/io/frame.rs index 13586382..f3db07e6 100644 --- a/src/io/frame.rs +++ b/src/io/frame.rs @@ -1,5 +1,6 @@ use std::fmt; use std::io; +use std::mem; use std::ops::{Deref, DerefMut}; use std::sync::Arc; @@ -209,6 +210,12 @@ impl fmt::Debug for EasyBuf { } } +impl Into> for EasyBuf { + fn into(mut self) -> Vec { + mem::replace(self.get_mut().buf, vec![]) + } +} + /// Encoding and decoding of frames via buffers. /// /// This trait is used when constructing an instance of `Framed`. It provides @@ -464,4 +471,49 @@ mod tests { assert_eq!(*buf.get_mut(), [3, 4, 5, 6, 7, 8]); mem::drop(clone); // prevent unused warning } + + #[test] + fn easybuf_into_vec_simple() { + let vec: Vec = (0u8..10u8).collect(); + let reference = vec.clone(); + let buf: EasyBuf = vec.into(); + let original_pointer = buf.buf.as_ref().as_ptr(); + let result: Vec = buf.into(); + assert_eq!(result, reference); + let new_pointer = result.as_ptr(); + assert_eq!(original_pointer, new_pointer, "Into> should be reuse the exclusive Vec"); + } + + #[test] + fn easybuf_into_vec_sliced() { + let vec: Vec = (0u8..10u8).collect(); + let mut buf: EasyBuf = vec.into(); + let original_pointer = buf.buf.as_ref().as_ptr(); + buf.split_off(9); + buf.drain_to(3); + let result: Vec = buf.into(); + let reference: Vec = (3u8..9u8).collect(); + assert_eq!(result, reference); + let new_pointer = result.as_ptr(); + assert_eq!(original_pointer, new_pointer, "Into> should be reuse the exclusive Vec"); + } + + #[test] + fn easybuf_into_vec_sliced_allocating() { + let vec: Vec = (0u8..10u8).collect(); + let mut buf: EasyBuf = vec.into(); + let original_pointer = buf.buf.as_ref().as_ptr(); + // Create a clone to create second reference to this EasyBuf and force allocation + let original = buf.clone(); + buf.split_off(9); + buf.drain_to(3); + let result: Vec = buf.into(); + let reference: Vec = (3u8..9u8).collect(); + assert_eq!(result, reference); + let original_reference: EasyBuf =(0u8..10u8).collect::>().into(); + assert_eq!(original.as_ref(), original_reference.as_ref()); + let new_pointer = result.as_ptr(); + assert_ne!(original_pointer, new_pointer, "A new vec should be allocated"); + } + }