qemu_command_builder/
serial.rs

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