tii 0.0.6

A Low-Latency Web Server.
Documentation
#![allow(dead_code)]
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::sync::{Arc, Mutex};
use tii::{ConnectionStream, IntoConnectionStream};

#[derive(Debug, Clone)]
pub struct MockStream {
  read_data: Arc<Mutex<VecDeque<u8>>>,
  write_data: Arc<Mutex<Vec<u8>>>,
}

impl MockStream {
  pub fn with_str(data: &str) -> Self {
    Self::with_data(VecDeque::from_iter(data.to_string().bytes()))
  }

  pub fn with_slice(data: &[u8]) -> Self {
    Self::with_data(VecDeque::from(data.to_vec()))
  }

  pub fn with_data(data: VecDeque<u8>) -> Self {
    Self { read_data: Arc::new(Mutex::new(data)), write_data: Arc::new(Mutex::new(Vec::new())) }
  }

  pub fn without_data() -> Self {
    Self::with_data(VecDeque::new())
  }

  pub fn copy_written_data(&self) -> Vec<u8> {
    self.write_data.lock().unwrap().clone()
  }

  pub fn copy_written_data_to_string(&self) -> String {
    String::from_utf8_lossy(self.copy_written_data().as_slice()).to_string()
  }

  pub fn to_stream(&self) -> Box<dyn ConnectionStream> {
    self.clone().into_connection_stream()
  }
}

impl IntoConnectionStream for MockStream {
  fn into_connection_stream(self) -> Box<dyn ConnectionStream> {
    let cl = self.clone();
    (Box::new(cl) as Box<dyn Read + Send>, Box::new(self) as Box<dyn Write + Send>)
      .into_connection_stream()
  }
}

impl Write for MockStream {
  fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
    self.write_data.lock().unwrap().write(buf)
  }

  fn flush(&mut self) -> std::io::Result<()> {
    Ok(())
  }
}

impl Read for MockStream {
  fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
    let mut bytes_written: usize = 0;

    for byte in buf {
      if let Some(new_byte) = self.read_data.lock().unwrap().pop_front() {
        *byte = new_byte;
        bytes_written += 1;
      } else {
        return Ok(bytes_written);
      }
    }

    Ok(bytes_written)
  }
}