bytes_deque 0.2.1

A growable bytes deque in Rust, providing access to the raw pointer.
Documentation
// Taken from <https://github.com/erdavila/linear-deque-rs/>; MIT
// licensed, (C) Eduardo R. D'Avila.

use std::alloc::{self, Layout};
use std::mem;
use std::ptr::NonNull;

#[derive(Debug)]
pub struct Buffer<T> {
    pub ptr: NonNull<T>,
    pub cap: usize,
}

unsafe impl<T: Send> Send for Buffer<T> {}
unsafe impl<T: Sync> Sync for Buffer<T> {}

impl<T> Buffer<T> {
    pub fn new() -> Self {
        let cap = if mem::size_of::<T>() == 0 {
            usize::MAX
        } else {
            0
        };

        Buffer {
            ptr: NonNull::dangling(),
            cap,
        }
    }

    pub fn realloc(&mut self, new_cap: usize) {
        let new_layout = Layout::array::<T>(new_cap).unwrap();

        let new_ptr = if self.cap == 0 {
            unsafe { alloc::alloc(new_layout) }
        } else {
            let old_layout = Layout::array::<T>(self.cap).unwrap();
            let old_ptr = self.ptr.as_ptr() as *mut u8;
            unsafe { alloc::realloc(old_ptr, old_layout, new_layout.size()) }
        };

        self.ptr = match NonNull::new(new_ptr as *mut T) {
            Some(p) => p,
            None => alloc::handle_alloc_error(new_layout),
        };
        self.cap = new_cap;
    }
}

impl<T> Drop for Buffer<T> {
    fn drop(&mut self) {
        let elem_size = mem::size_of::<T>();

        if self.cap != 0 && elem_size != 0 {
            unsafe {
                alloc::dealloc(
                    self.ptr.as_ptr() as *mut u8,
                    Layout::array::<T>(self.cap).unwrap(),
                );
            }
        }
    }
}