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(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}