timer-deque-rs 0.8.0

A OS based timer and timer queue which implements timeout queues of different types.
Documentation
#[cfg(target_family = "unix")]
pub mod unix
{
    pub use std::{cmp::Ordering, fmt, sync::Arc};

    pub use timer_deque_rs::
    {
        AbsoluteTime, 
        TimerDequeConsumer, 
        deque_timeout::{DequeOnce, OrderTimerDeque, OrderedTimerDequeMode}
    };
    pub use tokio::io::{Interest, unix::AsyncFd};


    #[derive(Debug, PartialEq, Eq, Clone)]
    pub struct TestItem(pub u64);

    impl fmt::Display for TestItem
    {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
        {
            write!(f, "0 = {}", self.0)
        }
    }

}

#[cfg(target_family = "unix")]
pub use self::unix::*;

#[cfg(target_family = "unix")]
#[tokio::main]
async fn main()
{
    let time_list = 
        OrderTimerDeque
            ::<DequeOnce, TimerDequeConsumer<Arc<TestItem>, _>>
            ::new("test_label_async".into(), 4, false, true)
                .unwrap();

    let mut time_list = 
        AsyncFd::try_with_interest(time_list, Interest::READABLE).unwrap();

    let abs_time = AbsoluteTime::now();

    let tss_set1 = DequeOnce::new(abs_time.clone().add_sec(3));
    let ent1 = Arc::new(TestItem(1));

    let tss_set2 = DequeOnce::new(abs_time.clone().add_sec(7));
    let ent2 = Arc::new(TestItem(2));

    let tss_set3 = DequeOnce::new(abs_time.clone().add_sec(10));
    let ent3 = Arc::new(TestItem(3));

    time_list.get_mut().add(ent1.clone(), tss_set1).unwrap();
    time_list.get_mut().add(ent2.clone(), tss_set2).unwrap();
    time_list.get_mut().add(ent3.clone(), tss_set3).unwrap();

    // ---- 
    // poll for event
    let mut guard = time_list.readable_mut().await.unwrap();
    
    let poll_timeout = AbsoluteTime::now();

    // read event from timer
    let timeout_items = guard.get_inner_mut().async_poll_for_event_and_process().await.unwrap();
    drop(guard);

    println!("timer timeout with result: {:?}", timeout_items);

    assert_eq!(timeout_items.is_some(), true);
    assert_eq!(timeout_items.as_ref().unwrap().len(), 1); // only one item
    assert_eq!(timeout_items.as_ref().unwrap()[0], ent1); // item 1

    let timeout_item = timeout_items.unwrap().pop().unwrap();
    
    println!("timer item: {}, timeout: {}, curtime: {}", timeout_item, tss_set1, poll_timeout);
    assert_eq!(tss_set1.get_absolut_timeout().seconds_cmp(&poll_timeout) == Ordering::Equal, true);

    // removing second item from queue, so ent3 should be next to fire
    let rem = time_list.get_mut().remove_from_queue(&ent2).unwrap();

    println!("item {:?} removed from shed. queue", rem);
    println!("queue len: {}", time_list.get_ref().timer_queue_len());

    assert_eq!(rem.is_some(), true);
    assert_eq!(rem, Some(ent2));
    assert_eq!(time_list.get_ref().timer_queue_len(), 1); // only ent3 left

    // -----
    // wait for events (ent3)

    // poll for event
    let mut guard = time_list.readable_mut().await.unwrap();
    
    let poll_timeout = AbsoluteTime::now();

    // read event from timer
    let timeout_items = guard.get_inner_mut().async_poll_for_event_and_process().await.unwrap();
    drop(guard);

    println!("timer timeout with result: {:?}", timeout_items);

    assert_eq!(timeout_items.is_some(), true);
    assert_eq!(timeout_items.as_ref().unwrap().len(), 1); // only one item
    assert_eq!(timeout_items.as_ref().unwrap()[0], ent3); // item 1

    let timeout_item = timeout_items.unwrap().pop().unwrap();
    
    println!("timer item: {}, timeout: {}, curtime: {}", timeout_item, tss_set1, poll_timeout);
    assert_eq!(tss_set1.get_absolut_timeout().seconds_cmp(&poll_timeout) == Ordering::Equal, true);


    println!("queue len: {}", time_list.get_ref().timer_queue_len());

    assert_eq!(time_list.get_ref().timer_queue_len(), 0); // queue should be empty

    return;
}

#[cfg(not(target_family = "unix"))]
fn main()
{
    panic!("Windows is experimental and MIO which is used in tokio does not support every HANDLE IOCP.");
}