mavlink_core/connection/udp/
config.rs1use core::fmt::Display;
2use std::io;
3use std::net::UdpSocket;
4use std::sync::{Arc, Mutex};
5use std::time::Duration;
6
7#[derive(Debug, Clone, Copy)]
20pub enum UdpMode {
21 Udpin,
23 Udpout,
25 UdpBroadcast,
27}
28
29#[derive(Debug, Clone)]
31pub struct UdpConfig {
32 pub(crate) address: String,
33 pub(crate) mode: UdpMode,
34 pub(crate) read_timeout: Option<Duration>,
35 pub(crate) source: UdpSource,
36}
37
38#[derive(Debug, Clone)]
39pub(crate) enum UdpSource {
40 Address,
41 Socket(Arc<Mutex<Option<UdpSocket>>>),
42}
43
44impl UdpConfig {
45 pub fn new(address: String, mode: UdpMode) -> Self {
49 Self {
50 address,
51 mode,
52 read_timeout: None,
53 source: UdpSource::Address,
54 }
55 }
56
57 pub fn from_socket(socket: UdpSocket, mode: UdpMode) -> io::Result<Self> {
63 let address = match mode {
64 UdpMode::Udpin => socket.local_addr()?,
65 UdpMode::Udpout | UdpMode::UdpBroadcast => socket.peer_addr()?,
66 };
67
68 Ok(Self {
69 address: address.to_string(),
70 mode,
71 read_timeout: None,
72 source: UdpSource::Socket(Arc::new(Mutex::new(Some(socket)))),
73 })
74 }
75
76 pub(crate) fn take_socket(&self) -> io::Result<Option<UdpSocket>> {
77 match &self.source {
78 UdpSource::Address => Ok(None),
79 UdpSource::Socket(socket) => socket
80 .lock()
81 .map_err(|_| io::Error::other("UDP socket lock poisoned"))?
82 .take()
83 .map(Some)
84 .ok_or_else(|| io::Error::other("UDP socket-backed configuration already used")),
85 }
86 }
87
88 pub fn read_timeout(mut self, timeout: Duration) -> Self {
94 self.read_timeout = Some(timeout);
95 self
96 }
97}
98
99impl Display for UdpConfig {
100 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
101 let mode = match self.mode {
102 UdpMode::Udpin => "udpin",
103 UdpMode::Udpout => "udpout",
104 UdpMode::UdpBroadcast => "udpbcast",
105 };
106 write!(f, "{mode}:{}", self.address)
107 }
108}