From b42d94c33baacf9ac90299497459ca8a6b4ac204 Mon Sep 17 00:00:00 2001
From: Carl Lerche <me@carllerche.com>
Date: Fri, 14 Oct 2016 20:42:32 -0700
Subject: [PATCH] Add BoundBuf

---
 src/imp/buf/bound.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++
 src/imp/buf/mod.rs   |  1 +
 2 files changed, 56 insertions(+)
 create mode 100644 src/imp/buf/bound.rs

diff --git a/src/imp/buf/bound.rs b/src/imp/buf/bound.rs
new file mode 100644
index 0000000..66cc2ca
--- /dev/null
+++ b/src/imp/buf/bound.rs
@@ -0,0 +1,55 @@
+use {Buf, IntoBuf};
+use std::mem;
+
+/// Takes a `T` that can be iterated as a buffer and provides buffer with a
+/// 'static lifetime
+pub struct BoundBuf<T>
+    where T: 'static,
+          &'static T: IntoBuf
+{
+    data: T, // This should never be mutated
+    buf: <&'static T as IntoBuf>::Buf, // This buf should never leak out
+}
+
+impl<T> BoundBuf<T>
+    where &'static T: IntoBuf,
+{
+    /// Creates a new `BoundBuf` wrapping the provided data
+    pub fn new(data: T) -> BoundBuf<T> {
+        let buf = unsafe {
+            let r: &'static T = mem::transmute(&data);
+            r.into_buf()
+        };
+
+        BoundBuf {
+            data: data,
+            buf: buf,
+        }
+    }
+
+    /// Consumes this BoundBuf, returning the underlying value.
+    pub fn into_inner(self) -> T {
+        self.data
+    }
+
+    /// Gets a reference to the underlying value
+    pub fn get_ref(&self) -> &T {
+        &self.data
+    }
+}
+
+impl<T> Buf for BoundBuf<T>
+    where &'static T: IntoBuf
+{
+    fn remaining(&self) -> usize {
+        self.buf.remaining()
+    }
+
+    fn bytes(&self) -> &[u8] {
+        self.buf.bytes()
+    }
+
+    fn advance(&mut self, cnt: usize) {
+        self.buf.advance(cnt)
+    }
+}
diff --git a/src/imp/buf/mod.rs b/src/imp/buf/mod.rs
index 118cc47..44c20f0 100644
--- a/src/imp/buf/mod.rs
+++ b/src/imp/buf/mod.rs
@@ -1,5 +1,6 @@
 pub mod append;
 pub mod block;
+pub mod bound;
 pub mod slice;
 pub mod ring;
 pub mod take;
-- 
GitLab