prettyping_rs/engine/
mod.rs1use std::net::IpAddr;
2use std::time::Duration;
3
4use thiserror::Error;
5
6pub mod mock;
7
8#[cfg(any(target_os = "linux", target_os = "macos"))]
9pub mod unix_surge;
10
11#[cfg(target_os = "windows")]
12pub mod windows_ping_async;
13
14pub type SequenceNumber = u64;
15pub type EngineTime = Duration;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ProbeRequest {
19 pub seq: SequenceNumber,
20 pub target: IpAddr,
21 pub sent_at: EngineTime,
22 pub payload_size: usize,
23 pub ttl: Option<u8>,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct PingReply {
28 pub seq: SequenceNumber,
29 pub ttl: Option<u8>,
30 pub payload_size: usize,
31 pub source: Option<IpAddr>,
32}
33
34impl PingReply {
35 #[must_use]
36 pub fn for_seq(seq: SequenceNumber) -> Self {
37 Self {
38 seq,
39 ttl: None,
40 payload_size: 0,
41 source: None,
42 }
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
47pub enum PingEvent {
48 Reply(PingReply),
49 Interrupt,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct TimedEvent {
54 pub at: EngineTime,
55 pub event: PingEvent,
56}
57
58#[derive(Debug, Error, Clone, PartialEq, Eq)]
59pub enum PingEngineError {
60 #[error("send failed for seq {seq}: {message}")]
61 SendFailed {
62 seq: SequenceNumber,
63 message: String,
64 },
65 #[error("poll failed: {message}")]
66 PollFailed { message: String },
67 #[error("invalid engine timeline: poll deadline moved backwards")]
68 NonMonotonicPoll,
69 #[error("invalid probe request for seq {seq}: {message}")]
70 InvalidProbeRequest {
71 seq: SequenceNumber,
72 message: String,
73 },
74}
75
76pub trait PingEngine {
77 fn now(&self) -> EngineTime;
78
79 fn send_probe(&mut self, request: ProbeRequest) -> Result<(), PingEngineError>;
80
81 fn poll_until(&mut self, deadline: EngineTime) -> Result<Vec<TimedEvent>, PingEngineError>;
92}