timer-deque-rs 0.6.0

A OS based timer and timer queue which implements timeout queues of different types.
Documentation
/*-
 * timer-deque-rs - a Rust crate which provides timer and timer queues based on target OS
 *  functionality.
 * 
 * Copyright (C) 2025 Aleksandr Morozov alex@nixd.org
 *  4neko.org alex@4neko.org
 * 
 * The timer-rs crate can be redistributed and/or modified
 * under the terms of either of the following licenses:
 *
 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
 *                     
 *   2. The MIT License (MIT)
 *                     
 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
 */

use std::fmt;

use crate::deque_timeout::{OrderedTimerDequeHandle, OrderedTimerDequeInterf, OrderedTimerDequeMode};
use crate::error::TimerResult;
use crate::timer_portable::timer::{AbsoluteTime, RelativeTime};



/// This type of the queue consumes the instance for which the timer is set. 
/// The item must be [Send] and [Clone], [std::sync::Arc]. This is convinient when it
/// is required to store the instance in the timer and retrive it when the 
/// timeout happens. This method allows to avoid for lookups in the lists and 
/// working directly with the stored items.
/// 
/// # Generics
/// 
/// `R` - an instance which should be stored on the timer dequeue. The instance
///     must implement [PartialEq], [Eq], [fmt::Debug], [fmt::Display], [Send].
/// 
/// `MODE` - a [OrderedTimerDequeMode] which defines the deque behaviour. There are
///     two types of the operation:
/// 
/// * [OrderdTimerDequeOnce] - after timeout the element is removed from the queue.
/// 
/// * [OrderdTimerDequePeriodic] - after timeout the element timeout is extended
///     until the item is not removed from the queue manually.
/// 
/// # Example
/// 
/// ```ignore
/// let mut time_list = 
///     OrderedTimerDeque
///         ::<DequeOnce, TimerDequeConsumer<u64, _>>
///         ::new("test_label1".into(), 4, false, true)
///            .unwrap();
/// ```
/// or
/// ```ignore
/// let mut time_list = 
///     OrderedTimerDeque
///         ::<DequePeriodic, TimerDequeConsumer<u64, _>>
///         ::new("test_label1".into(), 4, false, true)
///            .unwrap();
/// ```
#[derive(Debug)]
pub struct TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Debug + fmt::Display + Send + Clone,
    MODE: OrderedTimerDequeMode
{
    /// An internal data
    target: R,

    /// An absolute timestamp in seconds (UTC time) sets the timer.
    timeout_mode: MODE,
}

impl<R, MODE> fmt::Display 
for TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode
{  
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> 
    { 
        write!(f, "{} until: {}", self.target, self.timeout_mode)
    }
}

impl<R, MODE> TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone,
    MODE: OrderedTimerDequeMode
{ 
    fn into_inner(self) -> R
    {
        return self.target;
    }
}


impl<R, MODE> TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone,
    MODE: OrderedTimerDequeMode
{ 
    pub(super)
    fn new(target: R, time: MODE) -> TimerResult<Self>
    {
        time.validate_time(AbsoluteTime::now())?;

        return Ok(
            Self
            {
                target: 
                    target,
                timeout_mode: 
                   time,
            }
        );
    }
}

impl<R, MODE> Eq for TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode
{

}

impl<R, MODE> PartialEq for TimerDequeConsumer<R, MODE> 
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode
{
    fn eq(&self, other: &Self) -> bool 
    {
        return self.target == other.target;
    }
}

impl<R, MODE> PartialEq<R> for TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode 
{
    fn eq(&self, other: &R) -> bool 
    {
        return &self.target == other;
    }
}

impl<R, MODE> Ord for TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode 
{
    fn cmp(&self, other: &Self) -> std::cmp::Ordering 
    {
        return self.timeout_mode.cmp(&other.timeout_mode);
    }
}

impl<R, MODE> PartialOrd for TimerDequeConsumer<R, MODE>
where 
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
    MODE: OrderedTimerDequeMode 
{
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> 
    {
        return Some(self.cmp(other));
    }
}

impl<MODE, R> OrderedTimerDequeInterf<MODE> for TimerDequeConsumer<R, MODE>
where 
    MODE: OrderedTimerDequeMode,
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone
{
    #[inline]
    fn get_timeout_absolute(&self) -> AbsoluteTime 
    {
        return self.timeout_mode.get_absolut_timeout();
    }
}


impl<MODE, R> OrderedTimerDequeHandle<MODE> for TimerDequeConsumer<R, MODE>
where 
    MODE: OrderedTimerDequeMode,
    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone
{
    /// Input item.
    type TimerId = R;

    type HandleRes = Vec<Self::TimerId>;

    fn handle(mut self, timer_self: &mut super::OrderTimerDeque<MODE, Self>, 
        timer_ids: &mut Self::HandleRes) -> TimerResult<()>
    {
        timer_ids.push(self.target.clone());

        self.timeout_mode.advance_timeout();

        if MODE::IS_ONCE == false
        {
            return timer_self.queue_item(self);
        }
        else
        {
            return Ok(());
        }
    }

    #[inline]
    fn is_same(&self, other: &Self::TimerId) -> bool 
    {
        return &self.target == other;    
    }
    
    #[inline]
    fn postpone(&mut self, postp_time: RelativeTime) -> TimerResult<()> 
    {
        return self.timeout_mode.postpone(postp_time);
    }
    
    #[inline]
    fn resched(&mut self, time: MODE) -> TimerResult<()> 
    {
        self.timeout_mode = time;

        return Ok(());
    }

    #[inline]
    fn into_timer_id(self) -> Option<Self::TimerId>
    {
        return Some(self.into_inner());
    }
}