qemu_command_builder/args/
boot.rs1use crate::parsers::ARG_BOOT;
2use std::str::FromStr;
3
4use bon::Builder;
5use proptest_derive::Arbitrary;
6use winnow::Result;
7use winnow::ascii::{alphanumeric1, dec_uint};
8use winnow::combinator::opt;
9use winnow::prelude::*;
10use winnow::token::literal;
11
12use crate::common::OnOff;
13use crate::parsers::DELIM_COMMA;
14use crate::shell_string::{ShellString, ShellStringError, shell_string_until_comma};
15use crate::to_command::ToCommand;
16use crate::{pco0, ppo0, qao};
17
18const KEY_ORDER: &str = "order=";
19const KEY_ONCE: &str = "once=";
20const KEY_MENU: &str = "menu=";
21const KEY_SPLASH: &str = "splash=";
22const KEY_SPLASH_TIME: &str = "splash-time=";
23const KEY_REBOOT_TIMEOUT: &str = "reboot-timeout=";
24const KEY_STRICT: &str = "strict=";
25
26#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder, Arbitrary)]
56pub struct Boot {
57 order: Option<ShellString>,
58 once: Option<ShellString>,
59 menu: Option<OnOff>,
60 splash: Option<ShellString>,
61 splash_time: Option<usize>,
62 reboot_timeout: Option<usize>,
63 strict: Option<OnOff>,
64}
65
66impl ToCommand for Boot {
67 fn has_args(&self) -> bool {
68 self.order.is_some() || self.once.is_some() || self.menu.is_some() || self.splash.is_some() || self.splash_time.is_some() || self.reboot_timeout.is_some() || self.strict.is_some()
69 }
70
71 fn command(&self) -> String {
72 ARG_BOOT.to_string()
73 }
74 fn to_args(&self) -> Vec<String> {
75 let mut args = vec![];
76
77 if let Some(order) = &self.order {
78 args.push(format!("{}{}", KEY_ORDER, order.as_ref()));
79 }
80 if let Some(once) = &self.once {
81 args.push(format!("{}{}", KEY_ONCE, once.as_ref()));
82 }
83 qao!(&self.menu, args, KEY_MENU);
84 if let Some(splash) = &self.splash {
85 args.push(format!("{}{}", KEY_SPLASH, splash.as_ref()));
86 }
87 qao!(&self.splash_time, args, KEY_SPLASH_TIME);
88 qao!(&self.reboot_timeout, args, KEY_REBOOT_TIMEOUT);
89 qao!(&self.strict, args, KEY_STRICT);
90
91 vec![args.join(DELIM_COMMA)]
92 }
93}
94
95impl FromStr for Boot {
96 type Err = ShellStringError;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 boot.parse(s).map_err(|e| ShellStringError::from_parse(e))
100 }
101}
102
103pco0!(order, shell_string_until_comma, ShellString, KEY_ORDER);
104pco0!(once, shell_string_until_comma, ShellString, KEY_ONCE);
105pco0!(menu, alphanumeric1, OnOff, KEY_MENU);
106pco0!(splash, shell_string_until_comma, ShellString, KEY_SPLASH);
107ppo0!(splash_time, dec_uint, usize, KEY_SPLASH_TIME);
108ppo0!(reboot_timeout, dec_uint, usize, KEY_REBOOT_TIMEOUT);
109pco0!(strict, alphanumeric1, OnOff, KEY_STRICT);
110
111pub fn boot(s: &mut &str) -> ModalResult<Boot> {
112 let order = opt(order).parse_next(s)?;
113 let once = opt(once).parse_next(s)?;
114 let menu = opt(menu).parse_next(s)?;
115 let splash = opt(splash).parse_next(s)?;
116 let splash_time = opt(splash_time).parse_next(s)?;
117 let reboot_timeout = opt(reboot_timeout).parse_next(s)?;
118 let strict = opt(strict).parse_next(s)?;
119
120 Ok(Boot {
121 order,
122 once,
123 menu,
124 splash,
125 splash_time,
126 reboot_timeout,
127 strict,
128 })
129}