// TODO: replace "//" with "///" and fix TcpListener with Evented
// Associates readiness notifications with [`Evented`] handles.
//
// `Token` is a wrapper around `usize` and is used as an argument to
// [`Poll::register`] and [`Poll::reregister`].
//
// See [`Poll`] for more documentation on polling.
//
// # Example
//
// Using `Token` to track which socket generated the notification. In this
// example, `HashMap` is used, but usually something like [`slab`] is better.
//
// ```
// # use std::error::Error;
// # fn try_main() -> Result<(), Box<dyn Error>> {
// use urca::{Events, Ready, Poll, PollOpt, Token};
// use urca::net::TcpListener;
//
// use std::thread;
// use std::io::{self, Read};
// use std::collections::HashMap;
//
// // After this number of sockets is accepted, the server will shutdown.
// const MAX_SOCKETS: usize = 32;
//
// // Pick a token that will not be used by any other socket and use that one
// // for the listener.
// const LISTENER: Token = Token(1024);
//
// // Used to store the sockets.
// let mut sockets = HashMap::new();
//
// // This is used to generate a unique token for a socket
// let mut next_socket_index = 0;
//
// // The `Poll` instance
// let poll = Poll::new()?;
//
// // Tcp listener
// let listener = TcpListener::bind(&"127.0.0.1:0".parse()?)?;
//
// // Register the listener
// poll.register(&listener,
//               LISTENER,
//               Ready::readable(),
//               PollOpt::edge())?;
//
// // Spawn a thread that will connect a bunch of sockets then close them
// let addr = listener.local_addr()?;
// thread::spawn(move || {
//     use std::net::TcpStream;
//
//     // +1 here is to connect an extra socket to signal the socket to close
//     for _ in 0..(MAX_SOCKETS+1) {
//         // Connect then drop the socket
//         let _ = TcpStream::connect(&addr).unwrap();
//     }
// });
//
// // Event storage
// let mut events = Events::with_capacity(1024);
//
// // Read buffer, this will never actually get filled
// let mut buf = [0; 256];
//
// // The main event loop
// loop {
//     // Wait for events
//     poll.poll(&mut events, None)?;
//
//     for event in &events {
//         match event.token() {
//             LISTENER => {
//                 // Perform operations in a loop until `WouldBlock` is
//                 // encountered.
//                 loop {
//                     match listener.accept() {
//                         Ok((socket, _)) => {
//                             // Shutdown the server
//                             if next_socket_index == MAX_SOCKETS {
//                                 return Ok(());
//                             }
//
//                             // Get the token for the socket
//                             let token = Token(next_socket_index);
//                             next_socket_index += 1;
//
//                             // Register the new socket w/ poll
//                             poll.register(&socket,
//                                          token,
//                                          Ready::readable(),
//                                          PollOpt::edge())?;
//
//                             // Store the socket
//                             sockets.insert(token, socket);
//                         }
//                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
//                             // Socket is not ready anymore, stop accepting
//                             break;
//                         }
//                         e => panic!("err={:?}", e), // Unexpected error
//                     }
//                 }
//             }
//             token => {
//                 // Always operate in a loop
//                 loop {
//                     match sockets.get_mut(&token).unwrap().read(&mut buf) {
//                         Ok(0) => {
//                             // Socket is closed, remove it from the map
//                             sockets.remove(&token);
//                             break;
//                         }
//                         // Data is not actually sent in this example
//                         Ok(_) => unreachable!(),
//                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
//                             // Socket is not ready anymore, stop reading
//                             break;
//                         }
//                         e => panic!("err={:?}", e), // Unexpected error
//                     }
//                 }
//             }
//         }
//     }
// }
// #     Ok(())
// # }
// #
// # fn main() {
// #     try_main().unwrap();
// # }
// ```
//
/// [`Evented`]: event/trait.Evented.html
/// [`Poll`]: struct.Poll.html
/// [`Poll::register`]: struct.Poll.html#method.register
/// [`Poll::reregister`]: struct.Poll.html#method.reregister
/// [`slab`]: https://crates.io/crates/slab
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Token(pub usize);

impl From<usize> for Token {
    fn from(val: usize) -> Token {
        Token(val)
    }
}

impl From<Token> for usize {
    fn from(val: Token) -> usize {
        val.0
    }
}
