hopr_transport_mixer/
data.rs1use std::cmp::Ordering;
2
3pub struct DelayedData<T> {
8 pub release_at: std::time::Instant,
9 pub item: T,
10}
11
12impl<T> PartialEq for DelayedData<T> {
13 fn eq(&self, other: &Self) -> bool {
14 self.release_at == other.release_at
15 }
16}
17
18impl<T> PartialOrd for DelayedData<T> {
19 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
20 Some(self.cmp(other))
21 }
22}
23
24impl<T> Eq for DelayedData<T> {}
25
26impl<T> Ord for DelayedData<T> {
27 fn cmp(&self, other: &Self) -> Ordering {
28 self.release_at.cmp(&other.release_at)
29 }
30}
31
32impl<T> From<(std::time::Instant, T)> for DelayedData<T> {
33 fn from(value: (std::time::Instant, T)) -> Self {
34 Self {
35 release_at: value.0,
36 item: value.1,
37 }
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use std::time::{Duration, Instant};
44
45 use rstest::rstest;
46
47 use super::*;
48
49 #[rstest]
50 #[case::equal_timestamps(0, 0, Ordering::Equal)]
51 #[case::earlier_is_less(0, 1000, Ordering::Less)]
52 #[case::later_is_greater(1000, 0, Ordering::Greater)]
53 #[case::ordering_ignores_item_value(0, 0, Ordering::Equal)]
54 fn delayed_data_ordering(#[case] delay_a_ms: u64, #[case] delay_b_ms: u64, #[case] expected: Ordering) {
55 let now = Instant::now();
56 let a = DelayedData {
57 release_at: now + Duration::from_millis(delay_a_ms),
58 item: 1,
59 };
60 let b = DelayedData {
61 release_at: now + Duration::from_millis(delay_b_ms),
62 item: 2,
63 };
64 assert_eq!(a.cmp(&b), expected);
65 }
66
67 #[test]
68 fn from_tuple_sets_fields() {
69 let now = Instant::now();
70 let data = DelayedData::from((now, "hello"));
71 assert_eq!(data.release_at, now);
72 assert_eq!(data.item, "hello");
73 }
74
75 #[test]
76 fn sorting_respects_release_time() {
77 let now = Instant::now();
78 let mut items: Vec<DelayedData<&str>> = [(3, "c"), (1, "a"), (2, "b")]
79 .into_iter()
80 .map(|(secs, val)| DelayedData {
81 release_at: now + Duration::from_secs(secs),
82 item: val,
83 })
84 .collect();
85 items.sort();
86 let sorted: Vec<&str> = items.iter().map(|d| d.item).collect();
87 insta::assert_yaml_snapshot!(sorted);
88 }
89}