use std::{num, slice};
use dope_sys::Errno;
#[derive(Debug)]
pub struct Transfer<'a> {
input: &'a [u8],
steps: slice::Iter<'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: steps.iter(),
sent: Vec::new(),
}
}
fn step(&mut self) -> Result<usize, Errno> {
self.steps.next().copied().unwrap_or(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)
}