dope-sys 0.20.0

Typed operating-system call contracts
Documentation
use std::num;

use dope_sys::Errno;

#[derive(Debug)]
pub struct Transfer<'a> {
    input: &'a [u8],
    steps: &'a [Result<usize, Errno>],
    pub sent: Vec<u8>,
}

impl<'a> Transfer<'a> {
    pub fn new(input: &'a [u8], steps: &'a [Result<usize, Errno>]) -> Self {
        Self {
            input,
            steps,
            sent: Vec::new(),
        }
    }

    fn step(&mut self) -> Result<usize, Errno> {
        match self.steps.split_first() {
            Some((step, rest)) => {
                self.steps = rest;
                *step
            }
            None => Ok(usize::MAX),
        }
    }

    pub fn send<'b>(&mut self, input: &'b [u8]) -> Result<&'b [u8], Errno> {
        let extent = self.step()?.min(input.len());
        let sent = &input[..extent];
        self.sent.extend_from_slice(sent);
        Ok(sent)
    }

    pub fn recv<'b>(&mut self, output: &'b mut [u8]) -> Result<&'b mut [u8], Errno> {
        let extent = self.step()?.min(output.len()).min(self.input.len());
        let (received, rest) = self.input.split_at(extent);
        self.input = rest;
        let output = &mut output[..extent];
        output.copy_from_slice(received);
        Ok(output)
    }
}

pub fn frame(bytes: &[u8]) -> Result<Vec<u8>, num::TryFromIntError> {
    let length = u8::try_from(bytes.len())?;
    let mut frame = Vec::with_capacity(bytes.len() + 1);
    frame.push(length);
    frame.extend_from_slice(bytes);
    Ok(frame)
}