timer_deque_rs/deque_timeout/
timer_consumer.rs

1/*-
2 * timer-deque-rs - a Rust crate which provides timer and timer queues based on target OS
3 *  functionality.
4 * 
5 * Copyright (C) 2025 Aleksandr Morozov alex@nixd.org
6 *  4neko.org alex@4neko.org
7 * 
8 * The timer-rs crate can be redistributed and/or modified
9 * under the terms of either of the following licenses:
10 *
11 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
12 *                     
13 *   2. The MIT License (MIT)
14 *                     
15 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
16 */
17
18use std::fmt;
19
20use crate::deque_timeout::{OrderedTimerDequeHandle, OrderedTimerDequeInterf, OrderedTimerDequeMode};
21use crate::error::TimerResult;
22use crate::timer_portable::timer::{AbsoluteTime, RelativeTime};
23
24
25
26/// This type of the queue consumes the instance for which the timer is set. 
27/// The item must be [Send] and [Clone], [std::sync::Arc]. This is convinient when it
28/// is required to store the instance in the timer and retrive it when the 
29/// timeout happens. This method allows to avoid for lookups in the lists and 
30/// working directly with the stored items.
31/// 
32/// # Generics
33/// 
34/// `R` - an instance which should be stored on the timer dequeue. The instance
35///     must implement [PartialEq], [Eq], [fmt::Debug], [fmt::Display], [Send].
36/// 
37/// `MODE` - a [OrderedTimerDequeMode] which defines the deque behaviour. There are
38///     two types of the operation:
39/// 
40/// * [OrderdTimerDequeOnce] - after timeout the element is removed from the queue.
41/// 
42/// * [OrderdTimerDequePeriodic] - after timeout the element timeout is extended
43///     until the item is not removed from the queue manually.
44/// 
45/// # Example
46/// 
47/// ```ignore
48/// let mut time_list = 
49///     OrderedTimerDeque
50///         ::<DequeOnce, TimerDequeConsumer<u64, _>>
51///         ::new("test_label1".into(), 4, false, true)
52///            .unwrap();
53/// ```
54/// or
55/// ```ignore
56/// let mut time_list = 
57///     OrderedTimerDeque
58///         ::<DequePeriodic, TimerDequeConsumer<u64, _>>
59///         ::new("test_label1".into(), 4, false, true)
60///            .unwrap();
61/// ```
62#[derive(Debug)]
63pub struct TimerDequeConsumer<R, MODE>
64where 
65    R: PartialEq + Eq + fmt::Debug + fmt::Display + Send + Clone,
66    MODE: OrderedTimerDequeMode
67{
68    /// An internal data
69    target: R,
70
71    /// An absolute timestamp in seconds (UTC time) sets the timer.
72    timeout_mode: MODE,
73}
74
75impl<R, MODE> fmt::Display 
76for TimerDequeConsumer<R, MODE>
77where 
78    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
79    MODE: OrderedTimerDequeMode
80{  
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> 
82    { 
83        write!(f, "{} until: {}", self.target, self.timeout_mode)
84    }
85}
86
87impl<R, MODE> TimerDequeConsumer<R, MODE>
88where 
89    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone,
90    MODE: OrderedTimerDequeMode
91{ 
92    fn into_inner(self) -> R
93    {
94        return self.target;
95    }
96}
97
98
99impl<R, MODE> TimerDequeConsumer<R, MODE>
100where 
101    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone,
102    MODE: OrderedTimerDequeMode
103{ 
104    pub(super)
105    fn new(target: R, time: MODE) -> TimerResult<Self>
106    {
107        time.validate_time(AbsoluteTime::now())?;
108
109        return Ok(
110            Self
111            {
112                target: 
113                    target,
114                timeout_mode: 
115                   time,
116            }
117        );
118    }
119}
120
121impl<R, MODE> Eq for TimerDequeConsumer<R, MODE>
122where 
123    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
124    MODE: OrderedTimerDequeMode
125{
126
127}
128
129impl<R, MODE> PartialEq for TimerDequeConsumer<R, MODE> 
130where 
131    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
132    MODE: OrderedTimerDequeMode
133{
134    fn eq(&self, other: &Self) -> bool 
135    {
136        return self.target == other.target;
137    }
138}
139
140impl<R, MODE> PartialEq<R> for TimerDequeConsumer<R, MODE>
141where 
142    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
143    MODE: OrderedTimerDequeMode 
144{
145    fn eq(&self, other: &R) -> bool 
146    {
147        return &self.target == other;
148    }
149}
150
151impl<R, MODE> Ord for TimerDequeConsumer<R, MODE>
152where 
153    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
154    MODE: OrderedTimerDequeMode 
155{
156    fn cmp(&self, other: &Self) -> std::cmp::Ordering 
157    {
158        return self.timeout_mode.cmp(&other.timeout_mode);
159    }
160}
161
162impl<R, MODE> PartialOrd for TimerDequeConsumer<R, MODE>
163where 
164    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone, 
165    MODE: OrderedTimerDequeMode 
166{
167    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> 
168    {
169        return Some(self.cmp(other));
170    }
171}
172
173impl<MODE, R> OrderedTimerDequeInterf<MODE> for TimerDequeConsumer<R, MODE>
174where 
175    MODE: OrderedTimerDequeMode,
176    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone
177{
178    #[inline]
179    fn get_timeout_absolute(&self) -> AbsoluteTime 
180    {
181        return self.timeout_mode.get_absolut_timeout();
182    }
183}
184
185
186impl<MODE, R> OrderedTimerDequeHandle<MODE> for TimerDequeConsumer<R, MODE>
187where 
188    MODE: OrderedTimerDequeMode,
189    R: PartialEq + Eq + fmt::Display + fmt::Debug + Send + Clone
190{
191    /// Input item.
192    type TimerId = R;
193
194    type HandleRes = Vec<Self::TimerId>;
195
196    fn handle(mut self, timer_self: &mut super::OrderTimerDeque<MODE, Self>, 
197        timer_ids: &mut Self::HandleRes) -> TimerResult<()>
198    {
199        timer_ids.push(self.target.clone());
200
201        self.timeout_mode.advance_timeout();
202
203        if MODE::IS_ONCE == false
204        {
205            return timer_self.queue_item(self);
206        }
207        else
208        {
209            return Ok(());
210        }
211    }
212
213    #[inline]
214    fn is_same(&self, other: &Self::TimerId) -> bool 
215    {
216        return &self.target == other;    
217    }
218    
219    #[inline]
220    fn postpone(&mut self, postp_time: RelativeTime) -> TimerResult<()> 
221    {
222        return self.timeout_mode.postpone(postp_time);
223    }
224    
225    #[inline]
226    fn resched(&mut self, time: MODE) -> TimerResult<()> 
227    {
228        self.timeout_mode = time;
229
230        return Ok(());
231    }
232
233    #[inline]
234    fn into_timer_id(self) -> Option<Self::TimerId>
235    {
236        return Some(self.into_inner());
237    }
238}
239