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