1use std::collections::VecDeque;
2use std::net::SocketAddr;
3use std::time::Instant;
4
5#[derive(Debug, Clone)]
7pub struct QueuedDatagram {
8 pub delivery_time: Instant,
10 pub payload: Vec<u8>,
12 pub src: SocketAddr,
14 pub dst: SocketAddr,
16}
17
18#[derive(Debug, Default)]
20pub struct SimChannel {
21 queue: VecDeque<QueuedDatagram>,
22}
23
24impl SimChannel {
25 pub fn new() -> Self {
27 Self {
28 queue: VecDeque::new(),
29 }
30 }
31
32 pub fn push(&mut self, datagram: QueuedDatagram) {
34 let idx = self
36 .queue
37 .binary_search_by_key(&datagram.delivery_time, |d| d.delivery_time)
38 .unwrap_or_else(|x| x);
39 self.queue.insert(idx, datagram);
40 }
41
42 pub fn pop_ready(&mut self, now: Instant) -> Option<QueuedDatagram> {
44 if let Some(front) = self.queue.front() {
45 if front.delivery_time <= now {
46 return self.queue.pop_front();
47 }
48 }
49 None
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use std::time::Duration;
57
58 #[test]
59 fn test_sim_channel_ordering() {
60 let mut channel = SimChannel::new();
61 let now = Instant::now();
62 let src: SocketAddr = "127.0.0.1:1000".parse().unwrap();
63 let dst: SocketAddr = "127.0.0.1:2000".parse().unwrap();
64
65 channel.push(QueuedDatagram {
66 delivery_time: now + Duration::from_millis(20),
67 payload: vec![2],
68 src,
69 dst,
70 });
71
72 channel.push(QueuedDatagram {
73 delivery_time: now + Duration::from_millis(10),
74 payload: vec![1],
75 src,
76 dst,
77 });
78
79 assert!(channel.pop_ready(now).is_none());
81 assert!(channel.pop_ready(now + Duration::from_millis(15)).is_some());
82 assert!(channel.pop_ready(now + Duration::from_millis(15)).is_none());
83
84 let next = channel.pop_ready(now + Duration::from_millis(25)).unwrap();
85 assert_eq!(next.payload, vec![2]);
86 }
87}