use std::{io::{Write, ErrorKind, Read}, net::Shutdown};
use mio::net::TcpStream;
use self::Status::{Baby,Working,Dead};
#[derive(Debug,PartialEq, PartialOrd)]
pub enum Status {
Baby,
Working,
Dead,
}
#[derive(Debug)]
pub struct Line {
id:u64,
status:Status,
stream:TcpStream,
queue:Vec<u8>,
}
impl Line {
pub fn new(id:u64,stream:TcpStream) -> Line {
Line{ id,status:Baby,stream,queue:Vec::new() }
}
pub fn go_die(&mut self) {
self.queue.clear();
self.shutdown_stream();
self.set_status(Dead);
}
pub fn recv(&mut self) -> Vec<u8> {
let mut data:Vec<u8> = Vec::new();
let mut buf = [0;8192];
loop {
match self.stream.read(&mut buf) {
Ok(n) => {
if n > 0 {
data.extend_from_slice(&buf[..n]);
} else {
break;
}
}
Err(e) if e.kind() == ErrorKind::WouldBlock => { break; }
Err(e) => {
println!("{:?}",e);
break;
}
}
}
data
}
pub fn send(&mut self) {
if self.status != Working { return ; }
loop {
if self.queue.len() > 0 {
self.pour_queue();
} else {
break;
}
}
}
pub fn pour_queue(&mut self) {
match self.stream.write(&self.queue) {
Ok(n) => {
self.shrink_queue(n);
}
Err(err) => {
if err.kind() != ErrorKind::WouldBlock {
self.go_die();
}
}
}
}
pub fn shrink_queue(&mut self,n:usize) {
self.queue = self.queue[n..].to_vec();
}
pub fn on_writable(&mut self) {
self.set_status(Working);
self.send();
}
fn set_status(&mut self,v:Status) {
if v <= self.status { return; }
self.status = v;
}
fn shutdown_stream(&mut self) {
if self.status != Working { return; }
match self.stream.shutdown(Shutdown::Both) {
_ => {}
}
}
}