redevplugin_worker_sdk/
tcp.rs1use crate::api;
2use crate::error::Result;
3use crate::resource::{Handle, MAX_IO_CHUNK_BYTES};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize)]
7pub struct TcpConnect {
8 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 #[serde(default)]
16 pub no_delay: bool,
17 #[serde(default)]
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub keep_alive_ms: Option<u32>,
20}
21
22pub type ConnectOptions = TcpConnect;
23
24#[derive(Deserialize)]
25struct HandleResult {
26 handle: u64,
27}
28
29pub struct TcpStream {
30 handle: Handle,
31}
32
33impl TcpStream {
34 pub fn connect(options: TcpConnect) -> Result<Self> {
35 let opened: HandleResult = api::call("net.tcp.connect", &options)?;
36 Ok(Self {
37 handle: Handle::new(opened.handle)?,
38 })
39 }
40
41 pub fn read(&mut self, capacity: usize) -> Result<(Vec<u8>, u32)> {
42 self.handle.read(capacity)
43 }
44
45 pub fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
46 for chunk in bytes.chunks(MAX_IO_CHUNK_BYTES) {
47 self.handle.write(chunk, 0)?;
48 }
49 Ok(())
50 }
51
52 pub fn shutdown(&mut self, direction: Shutdown) -> Result<()> {
53 #[derive(Serialize)]
54 struct Arguments {
55 handle: u64,
56 direction: Shutdown,
57 }
58 let _: serde_json::Value = api::call(
59 "net.tcp.shutdown",
60 &Arguments {
61 handle: self.handle.id(),
62 direction,
63 },
64 )?;
65 Ok(())
66 }
67
68 pub fn close(mut self) -> Result<()> {
69 self.handle.close()
70 }
71}
72
73#[derive(Debug, Clone, Copy, Serialize)]
74#[serde(rename_all = "snake_case")]
75pub enum Shutdown {
76 Read,
77 Write,
78 Both,
79}
80
81#[derive(Debug, Clone, Serialize)]
82pub struct TcpListen {
83 pub host: String,
84 pub port: u16,
85}
86
87pub type ListenOptions = TcpListen;
88
89#[derive(Deserialize)]
90struct ListenResult {
91 handle: u64,
92 address: String,
93}
94
95pub struct TcpListener {
96 handle: Handle,
97 pub address: String,
98}
99
100impl TcpListener {
101 pub fn listen(options: TcpListen) -> Result<Self> {
102 let opened: ListenResult = api::call("net.tcp.listen", &options)?;
103 Ok(Self {
104 handle: Handle::new(opened.handle)?,
105 address: opened.address,
106 })
107 }
108
109 pub fn accept(&mut self, no_delay: bool, keep_alive_ms: Option<u32>) -> Result<TcpStream> {
110 #[derive(Serialize)]
111 struct Arguments {
112 handle: u64,
113 no_delay: bool,
114 #[serde(skip_serializing_if = "Option::is_none")]
115 keep_alive_ms: Option<u32>,
116 }
117 let opened: HandleResult = api::call(
118 "net.tcp.accept",
119 &Arguments {
120 handle: self.handle.id(),
121 no_delay,
122 keep_alive_ms,
123 },
124 )?;
125 Ok(TcpStream {
126 handle: Handle::new(opened.handle)?,
127 })
128 }
129
130 pub fn close(mut self) -> Result<()> {
131 self.handle.close()
132 }
133}