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