Skip to main content

redevplugin_worker_sdk/
udp.rs

1use crate::api;
2use crate::error::{Error, Result};
3use crate::resource::{Handle, IO_FLAG_DATAGRAM_END, MAX_IO_CHUNK_BYTES};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize)]
7pub struct UdpConnect {
8    pub host: String,
9    pub port: u16,
10    #[serde(default)]
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub timeout_ms: Option<u32>,
13}
14
15pub type ConnectOptions = UdpConnect;
16
17#[derive(Deserialize)]
18struct HandleResult {
19    handle: u64,
20}
21
22pub struct UdpSocket {
23    handle: Handle,
24}
25
26impl UdpSocket {
27    pub fn connect(options: UdpConnect) -> Result<Self> {
28        let opened: HandleResult = api::call("net.udp.connect", &options)?;
29        Ok(Self {
30            handle: Handle::new(opened.handle)?,
31        })
32    }
33
34    pub fn send(&mut self, datagram: &[u8]) -> Result<()> {
35        if datagram.len() > MAX_IO_CHUNK_BYTES {
36            return Err(Error::from_abi_status(-11));
37        }
38        self.handle.write(datagram, IO_FLAG_DATAGRAM_END)
39    }
40
41    pub fn receive(&mut self) -> Result<Vec<u8>> {
42        let (body, flags) = self.handle.read(MAX_IO_CHUNK_BYTES)?;
43        if flags & IO_FLAG_DATAGRAM_END == 0 {
44            return Err(Error::internal("UDP datagram boundary is missing"));
45        }
46        Ok(body)
47    }
48
49    pub fn close(mut self) -> Result<()> {
50        self.handle.close()
51    }
52}