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