Skip to main content

qemu_command_builder/args/
name.rs

1use crate::parsers::ARG_NAME;
2use bon::Builder;
3use proptest_derive::Arbitrary;
4use std::str::FromStr;
5
6use crate::common::OnOff;
7use crate::parsers::DELIM_COMMA;
8use crate::qao;
9use crate::shell_string::{ShellString, ShellStringError};
10use crate::to_command::ToCommand;
11
12const KEY_PROCESS: &str = "process=";
13const KEY_DEBUG_THREADS: &str = "debug-threads=";
14
15/// Sets the name of the guest. This name will be displayed in the SDL
16/// window caption. The name will also be used for the VNC server. Also
17/// optionally set the top visible process name in Linux. Naming of
18/// individual threads can also be enabled on Linux to aid debugging.
19#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder, Arbitrary)]
20pub struct Name {
21    /// The guest name shown by QEMU frontends.
22    name: ShellString,
23    /// Optional process name visible on the host.
24    process: Option<ShellString>,
25    /// Whether QEMU should name individual threads.
26    debug_threads: Option<OnOff>,
27}
28
29impl ToCommand for Name {
30    fn command(&self) -> String {
31        ARG_NAME.to_string()
32    }
33    fn to_args(&self) -> Vec<String> {
34        let mut args = vec![self.name.as_ref().to_string()];
35
36        if let Some(process) = &self.process {
37            args.push(format!("{}{}", KEY_PROCESS, process.as_ref()));
38        }
39        qao!(&self.debug_threads, args, KEY_DEBUG_THREADS);
40
41        vec![args.join(DELIM_COMMA)]
42    }
43}
44
45impl FromStr for Name {
46    type Err = ShellStringError;
47
48    fn from_str(s: &str) -> Result<Self, Self::Err> {
49        let mut parts = s.split(DELIM_COMMA);
50        let first = parts.next().ok_or_else(|| ShellStringError::new("empty -name argument"))?;
51
52        let mut process = None;
53        let mut debug_threads = None;
54
55        for part in parts {
56            let (key, value) = part.split_once('=').ok_or_else(|| ShellStringError::new(format!("invalid -name option: {part}")))?;
57            match key {
58                "process" => process = Some(ShellString::new(value)),
59                "debug-threads" => debug_threads = Some(value.parse::<OnOff>().map_err(|_| ShellStringError::new(format!("invalid debug-threads value: {value}")))?),
60                other => return Err(ShellStringError::new(format!("unsupported -name option: {other}"))),
61            }
62        }
63
64        Ok(Name {
65            name: ShellString::new(first),
66            process,
67            debug_threads,
68        })
69    }
70}