1use std::{
3 fmt,
4 net::{Ipv4Addr, SocketAddrV4},
5 sync::Arc,
6 time::Duration,
7};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub enum MappingProtocol {
12 Pcp,
13 NatPmp,
14 Upnp,
15}
16
17#[derive(Clone, Debug)]
19#[non_exhaustive]
20pub enum Event {
21 Discovering,
22 Gateway {
23 local_ip: Ipv4Addr,
24 gateway: Ipv4Addr,
25 },
26 Discovered(super::ProbeOutput),
27 DiscoveryFailed(String),
28 Requesting {
29 protocol: MappingProtocol,
30 gateway: Ipv4Addr,
31 renewal: bool,
32 },
33 Active {
34 protocol: MappingProtocol,
35 external: SocketAddrV4,
36 lifetime: Duration,
37 },
38 MappingFailed(String),
39 Expired(SocketAddrV4),
40 Cancelled,
41 Releasing(SocketAddrV4),
42 Released {
45 external: SocketAddrV4,
46 confirmed: bool,
47 },
48 ReleaseFailed {
49 external: SocketAddrV4,
50 error: String,
51 },
52}
53
54#[derive(Clone, Default)]
57pub struct Observer(Option<Arc<dyn Fn(Event) + Send + Sync>>);
58
59impl Observer {
60 pub fn new(callback: impl Fn(Event) + Send + Sync + 'static) -> Self {
61 Self(Some(Arc::new(callback)))
62 }
63 pub(crate) fn emit(&self, event: Event) {
64 if let Some(callback) = &self.0 {
65 callback(event);
66 }
67 }
68}
69impl fmt::Debug for Observer {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.debug_struct("Observer")
72 .field("enabled", &self.0.is_some())
73 .finish()
74 }
75}
76
77pub(crate) fn detail(error: impl fmt::Display) -> String {
78 error.to_string().chars().take(256).collect()
79}