1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use std::io::{ self, ErrorKind, Read, Stdin as StdStdin, stdin, }; use crate::aio::poll::Mode; use crate::aio::poll::ffi::epoll_event; use crate::aio::handler::{ Loop, Handler, Stream, }; use crate::aio::net::set_nonblocking; use self::Msg::*; enum Msg { Read(epoll_event), } struct StdinHandler<NOTIFY> { input_notify: NOTIFY, stdin: StdStdin, } impl<NOTIFY> StdinHandler<NOTIFY> { fn new(input_notify: NOTIFY) -> io::Result<Self> { let stdin = stdin(); set_nonblocking(&stdin)?; Ok(Self { input_notify, stdin, }) } } impl<NOTIFY> Handler for StdinHandler<NOTIFY> where NOTIFY: InputNotify, { type Msg = Msg; fn update(&mut self, _stream: &Stream<Msg>, msg: Msg) { match msg { Read(event) => { if event.events & Mode::Read as u32 != 0 { let mut buffer = vec![0; 4096]; match self.stdin.read(&mut buffer) { Err(ref error) if error.kind() == ErrorKind::WouldBlock || error.kind() == ErrorKind::Interrupted => (), Ok(bytes_read) => { if bytes_read > 0 { buffer.truncate(bytes_read); self.input_notify.received(buffer); } }, _ => (), } } }, } } } pub struct Stdin { } impl Stdin { pub fn new<NOTIFY>(event_loop: &mut Loop, input_notify: NOTIFY) -> io::Result<()> where NOTIFY: InputNotify + 'static, { let stdin = stdin(); set_nonblocking(&stdin)?; let stream = event_loop.spawn(StdinHandler::new(input_notify)?); event_loop.add_fd(&stdin, Mode::Read, &stream, Read) } } pub trait InputNotify { fn received(&mut self, data: Vec<u8>); }