/// Associates readiness events with [`event::Source`]s.
///
/// `Token` is a wrapper around `usize` and is used as an argument to
/// [`Registry::register`] and [`Registry::reregister`].
///
/// See [`Poll`] for more documentation on polling.
///
/// [`event::Source`]: crate::event::Source
/// [`Poll`]: crate::Poll
/// [`Registry::register`]: crate::Registry::register
/// [`Registry::reregister`]: crate::Registry::reregister
///
/// # Example
///
/// Using `Token` to track which socket generated the event. In this example,
/// `HashMap` is used, but usually something like [`slab`] is better.
///
/// [`slab`]: https://crates.io/crates/slab
///
/// ```
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// use mio::{Events, Interests, Poll, Token};
/// use mio::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 mut poll = Poll::new()?;
///
/// // Tcp listener
/// let listener = TcpListener::bind("127.0.0.1:0".parse()?)?;
///
/// // Register the listener
/// poll.registry().register(&listener, LISTENER, Interests::READABLE)?;
///
/// // 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.registry().register(&socket, token, Interests::READABLE)?;
///
///                             // 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
///                     }
///                 }
///             }
///         }
///     }
/// }
/// # }
/// ```
#[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
    }
}
