nell 0.3.0

Linux netlink interface
Documentation
// Copyright (C) 2020 - Will Glozer. All rights reserved.

use std::mem::transmute;
use libc::_SC_PAGESIZE;
use crate::sys::*;

pub struct Buffer {
    buf: Vec<u8>,
    cur: usize,
    end: usize,
}

#[derive(Debug, PartialEq)]
pub enum Either<'a, 'b, T: Bytes> {
    A(Netlink<Message<'a, T>>),
    B(&'b mut [u8]),
}

impl Buffer {
    pub fn new() -> Self {
        let size = pagesize() * 2;
        Self {
            buf: vec![0u8; size],
            cur: 0,
            end: 0,
        }
    }

    pub unsafe fn next<'a, T: Bytes>(&mut self) -> Result<Either<'a, '_, T>, Error> {
        let ready = self.end - self.cur;

        let read  = &self.buf[self.cur..self.end];
        let read: &'a [u8] = transmute(read);
        let write = &mut self.buf;

        let mut c = Cursor::from(read);

        if let Some(next) = reader::next(&mut c) {
            let unread = c.bytes().len();
            self.cur += ready - unread;
            return Ok(Either::A(next?));
        }

        Ok(Either::B(write))
    }

    pub fn provide(&mut self, n: usize) {
        self.cur = 0;
        self.end = n;
    }
}

fn pagesize() -> usize {
    unsafe {
        libc::sysconf(_SC_PAGESIZE) as usize
    }
}