lapin-async 0.22.1

AMQP client library with a low level API designed for use with mio
Documentation
use std::{cmp, ptr};

#[derive(Debug,PartialEq,Clone)]
pub(crate) struct Buffer {
  memory:   Vec<u8>,
  capacity: usize,
  position: usize,
  end:      usize
}

impl Buffer {
  pub(crate) fn with_capacity(capacity: usize) -> Buffer {
    Buffer {
      memory:   vec![0; capacity],
      capacity,
      position: 0,
      end:      0
    }
  }

  pub(crate) fn grow(&mut self, new_size: usize) -> bool {
    if self.capacity >= new_size {
      return false;
    }

    self.memory.resize(new_size, 0);
    self.capacity = new_size;
    true
  }

  pub(crate) fn available_data(&self) -> usize {
    self.end - self.position
  }

  pub(crate) fn available_space(&self) -> usize {
    self.capacity - self.end
  }

  pub(crate) fn consume(&mut self, count: usize) -> usize {
    let cnt        = cmp::min(count, self.available_data());
    self.position += cnt;
    cnt
  }

  pub(crate) fn fill(&mut self, count: usize) -> usize {
    let cnt   = cmp::min(count, self.available_space());
    self.end += cnt;
    cnt
  }

  pub(crate) fn data(&self) -> &[u8] {
    &self.memory[self.position..self.end]
  }

  pub(crate) fn space(&mut self) -> &mut [u8] {
    &mut self.memory[self.end..self.capacity]
  }

  pub(crate) fn shift(&mut self) {
    let length = self.end - self.position;
    unsafe {
      ptr::copy((&self.memory[self.position..self.end]).as_ptr(), (&mut self.memory[..length]).as_mut_ptr(), length);
    }
    self.position = 0;
    self.end      = length;
  }

  pub(crate) fn shift_unless_available(&mut self, size: usize) {
    if self.available_space() < size {
      self.shift();
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use std::io::Write;

  #[test]
  fn fill_and_consume() {
    let mut b = Buffer::with_capacity(10);
    assert_eq!(b.available_data(), 0);
    assert_eq!(b.available_space(), 10);
    let res = b.space().write(&b"abcd"[..]).map(|size| { b.fill(size); size });
    assert_eq!(res.ok(), Some(4));
    assert_eq!(b.available_data(), 4);
    assert_eq!(b.available_space(), 6);

    assert_eq!(b.data(), &b"abcd"[..]);

    b.consume(2);
    assert_eq!(b.available_data(), 2);
    assert_eq!(b.available_space(), 6);
    assert_eq!(b.data(), &b"cd"[..]);

    b.shift();
    assert_eq!(b.available_data(), 2);
    assert_eq!(b.available_space(), 8);
    assert_eq!(b.data(), &b"cd"[..]);

    assert_eq!(b.space().write(&b"efghijklmnop"[..]).map(|size| { b.fill(size); size }).ok(), Some(8));
    assert_eq!(b.available_data(), 10);
    assert_eq!(b.available_space(), 0);
    assert_eq!(b.data(), &b"cdefghijkl"[..]);
    b.shift();
    assert_eq!(b.available_data(), 10);
    assert_eq!(b.available_space(), 0);
    assert_eq!(b.data(), &b"cdefghijkl"[..]);
  }
}