1use std::path::PathBuf;
2
3use bon::Builder;
4
5use crate::common::OnOff;
6use crate::to_command::{ToArg, ToCommand};
7
8#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
9pub struct VC {
10 is_pixel: bool,
11 w: usize,
12 h: usize,
13}
14
15#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
16pub struct Udp {
17 remote_host: Option<String>,
18 remote_port: u16,
19 src_ip: Option<String>,
20 src_port: Option<u16>,
21}
22
23#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
24pub struct Tcp {
25 host: String,
26 port: u16,
27 server: Option<OnOff>,
28 wait: Option<OnOff>,
29 nodelay: Option<OnOff>,
30 reconnect_ms: Option<usize>,
31}
32
33#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
34pub struct Telnet {
35 host: String,
36 port: u16,
37 server: Option<OnOff>,
38 wait: Option<OnOff>,
39 nodelay: Option<OnOff>,
40}
41
42#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
43pub struct Websocket {
44 host: String,
45 port: u16,
46 server: Option<OnOff>,
47 wait: Option<OnOff>,
48 nodelay: Option<OnOff>,
49}
50
51#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
52pub struct Unix {
53 path: PathBuf,
54 server: Option<OnOff>,
55 wait: Option<OnOff>,
56 reconnect_ms: Option<usize>,
57}
58
59#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
60pub enum SpecialDevice {
61 VC(Option<VC>),
62 Pty(Option<PathBuf>),
63 None,
64 Null,
65 Chardev(String),
66 Dev(String),
67 Parport(usize),
68 File(PathBuf),
69 Stdio,
70 Pipe(PathBuf),
71 Com(usize),
72 Udp(Udp),
73 Tcp(Tcp),
74 Telnet(Telnet),
75 Websocket(Websocket),
76 Unix(Unix),
77 Mon(String),
78 Braille,
79 Msmouse,
80}
81
82impl ToCommand for SpecialDevice {
83 fn to_command(&self) -> Vec<String> {
84 let mut cmd = vec![];
85
86 let mut args = vec![];
87
88 match self {
89 SpecialDevice::VC(vc) => {
90 if let Some(vc) = vc {
91 if vc.is_pixel {
92 args.push(format!("vc:{}x{}", vc.w, vc.h));
93 } else {
94 args.push(format!("vc:{}Cx{}C", vc.w, vc.h));
95 }
96 } else {
97 args.push("vc".to_string());
98 }
99 }
100 SpecialDevice::Pty(pty) => {
101 if let Some(pty) = pty {
102 args.push(format!("pty:{}", pty.display()));
103 } else {
104 args.push("pty".to_string());
105 }
106 }
107 SpecialDevice::None => {
108 args.push("none".to_string());
109 }
110 SpecialDevice::Null => {
111 args.push("null".to_string());
112 }
113 SpecialDevice::Chardev(chardev) => {
114 args.push(format!("chardev:{}", chardev));
115 }
116 SpecialDevice::Dev(dev) => {
117 args.push(format!("/dev/{}", dev));
118 }
119 SpecialDevice::Parport(parport) => {
120 args.push(format!("/dev/parport{}", parport));
121 }
122 SpecialDevice::File(file) => {
123 args.push(format!("file:{}", file.display()));
124 }
125 SpecialDevice::Stdio => {
126 args.push("stdio".to_string());
127 }
128 SpecialDevice::Pipe(pipe) => {
129 args.push(format!("pipe:{}", pipe.display()));
130 }
131 SpecialDevice::Com(com) => {
132 args.push(format!("COM{}", com));
133 }
134 SpecialDevice::Udp(udp) => {
135 let mut udpargs = vec![];
136
137 udpargs.push("udp".to_string());
138 if let Some(remote_host) = &udp.remote_host {
139 udpargs.push(remote_host.to_string());
140 }
141 udpargs.push(format!("{}", udp.remote_port));
142 if let Some(src_ip) = &udp.src_ip {
143 udpargs.push(format!("@{}", src_ip));
144 }
145 if let Some(src_port) = &udp.src_port {
146 udpargs.push(format!("{}", src_port));
147 }
148 args.push(udpargs.join(":"));
149 }
150 SpecialDevice::Tcp(tcp) => {
151 let mut tcpargs = vec![];
152
153 tcpargs.push(format!("tcp:{}:{}", tcp.host, tcp.port));
154 if let Some(server) = &tcp.server {
155 tcpargs.push(format!("server={}", server.to_arg()));
156 }
157 if let Some(wait) = &tcp.wait {
158 tcpargs.push(format!("wait={}", wait.to_arg()));
159 }
160 if let Some(nodelay) = &tcp.nodelay {
161 tcpargs.push(format!("nodelay={}", nodelay.to_arg()));
162 }
163 if let Some(reconnect_ms) = &tcp.reconnect_ms {
164 tcpargs.push(format!("reconnect-ms={}", reconnect_ms));
165 }
166 args.push(tcpargs.join(","));
167 }
168 SpecialDevice::Telnet(telnet) => {
169 let mut telnetargs = vec![];
170
171 telnetargs.push(format!("telnet:{}:{}", telnet.host, telnet.port));
172 if let Some(server) = &telnet.server {
173 telnetargs.push(format!("server={}", server.to_arg()));
174 }
175 if let Some(wait) = &telnet.wait {
176 telnetargs.push(format!("wait={}", wait.to_arg()));
177 }
178 if let Some(nodelay) = &telnet.nodelay {
179 telnetargs.push(format!("nodelay={}", nodelay.to_arg()));
180 }
181 args.push(telnetargs.join(","));
182 }
183 SpecialDevice::Websocket(ws) => {
184 let mut wsargs = vec![];
185
186 wsargs.push(format!("websocket:{}:{}", ws.host, ws.port));
187 if let Some(server) = &ws.server {
188 wsargs.push(format!("server={}", server.to_arg()));
189 }
190 if let Some(wait) = &ws.wait {
191 wsargs.push(format!("wait={}", wait.to_arg()));
192 }
193 if let Some(nodelay) = &ws.nodelay {
194 wsargs.push(format!("nodelay={}", nodelay.to_arg()));
195 }
196 args.push(wsargs.join(","));
197 }
198 SpecialDevice::Unix(uds) => {
199 let mut udsargs = vec![];
200
201 udsargs.push(format!("unix:{}", uds.path.display()));
202 if let Some(server) = &uds.server {
203 udsargs.push(format!("server={}", server.to_arg()));
204 }
205 if let Some(wait) = &uds.wait {
206 udsargs.push(format!("wait={}", wait.to_arg()));
207 }
208 if let Some(reconnect_ms) = &uds.reconnect_ms {
209 udsargs.push(format!("reconnect-ms={}", reconnect_ms));
210 }
211 args.push(udsargs.join(","));
212 }
213 SpecialDevice::Mon(mon) => {
214 args.push(format!("mon:{}", mon));
215 }
216 SpecialDevice::Braille => {
217 args.push("braille".to_string());
218 }
219 SpecialDevice::Msmouse => {
220 args.push("msmouse".to_string());
221 }
222 }
223 cmd.push(args.join("").to_string());
224 cmd
225 }
226}