/// General IO module. /// /// Example usage for craeting a network service and adding an IO handler: /// /// ```rust /// extern crate ethcore_util; /// use ethcore_util::*; /// /// struct MyHandler; /// /// struct MyMessage { /// data: u32 /// } /// /// impl IoHandler for MyHandler { /// fn initialize(&mut self, io: &mut IoContext) { /// io.register_timer(1000).unwrap(); /// } /// /// fn timeout(&mut self, _io: &mut IoContext, timer: TimerToken) { /// println!("Timeout {}", timer); /// } /// /// fn message(&mut self, _io: &mut IoContext, message: &mut MyMessage) { /// println!("Message {}", message.data); /// } /// } /// /// fn main () { /// let mut service = IoService::::start().expect("Error creating network service"); /// service.register_handler(Box::new(MyHandler)).unwrap(); /// /// // Wait for quit condition /// // ... /// // Drop the service /// } /// ``` mod service; #[derive(Debug)] pub enum IoError { Mio(::std::io::Error), } impl From<::mio::NotifyError>> for IoError where Message: Send { fn from(_err: ::mio::NotifyError>) -> IoError { IoError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) } } /// Generic IO handler. /// All the handler function are called from within IO event loop. /// `Message` type is used as notification data pub trait IoHandler: Send where Message: Send + 'static { /// Initialize the handler fn initialize<'s>(&'s mut self, _io: &mut IoContext<'s, Message>) {} /// Timer function called after a timeout created with `HandlerIo::timeout`. fn timeout<'s>(&'s mut self, _io: &mut IoContext<'s, Message>, _timer: TimerToken) {} /// Called when a broadcasted message is received. The message can only be sent from a different IO handler. fn message<'s>(&'s mut self, _io: &mut IoContext<'s, Message>, _message: &'s mut Message) {} // TODO: make message immutable and provide internal channel for adding network handler /// Called when an IO stream gets closed fn stream_hup<'s>(&'s mut self, _io: &mut IoContext<'s, Message>, _stream: StreamToken) {} /// Called when an IO stream can be read from fn stream_readable<'s>(&'s mut self, _io: &mut IoContext<'s, Message>, _stream: StreamToken) {} /// Called when an IO stream can be written to fn stream_writable<'s>(&'s mut self, _io: &mut IoContext<'s, Message>, _stream: StreamToken) {} } pub type TimerToken = service::TimerToken; pub type StreamToken = service::StreamToken; pub type IoContext<'s, M> = service::IoContext<'s, M>; pub type IoService = service::IoService; pub type IoChannel = service::IoChannel; //pub const USER_TOKEN_START: usize = service::USER_TOKEN; // TODO: ICE in rustc 1.7.0-nightly (49c382779 2016-01-12) #[cfg(test)] mod tests { use io::*; struct MyHandler; struct MyMessage { data: u32 } impl IoHandler for MyHandler { fn initialize(&mut self, io: &mut IoContext) { io.register_timer(1000).unwrap(); } fn timeout(&mut self, _io: &mut IoContext, timer: TimerToken) { println!("Timeout {}", timer); } fn message(&mut self, _io: &mut IoContext, message: &mut MyMessage) { println!("Message {}", message.data); } } #[test] fn test_service_register_handler () { let mut service = IoService::::start().expect("Error creating network service"); service.register_handler(Box::new(MyHandler)).unwrap(); } }