use crate::parsers::ARG_BOOT;
use std::str::FromStr;
use bon::Builder;
use proptest_derive::Arbitrary;
use winnow::Result;
use winnow::ascii::{alphanumeric1, dec_uint};
use winnow::combinator::opt;
use winnow::prelude::*;
use winnow::token::literal;
use crate::common::OnOff;
use crate::parsers::DELIM_COMMA;
use crate::shell_string::{ShellString, ShellStringError, shell_string_until_comma};
use crate::to_command::ToCommand;
use crate::{pco0, ppo0, qao};
const KEY_ORDER: &str = "order=";
const KEY_ONCE: &str = "once=";
const KEY_MENU: &str = "menu=";
const KEY_SPLASH: &str = "splash=";
const KEY_SPLASH_TIME: &str = "splash-time=";
const KEY_REBOOT_TIMEOUT: &str = "reboot-timeout=";
const KEY_STRICT: &str = "strict=";
#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder, Arbitrary)]
pub struct Boot {
order: Option<ShellString>,
once: Option<ShellString>,
menu: Option<OnOff>,
splash: Option<ShellString>,
splash_time: Option<usize>,
reboot_timeout: Option<usize>,
strict: Option<OnOff>,
}
impl ToCommand for Boot {
fn has_args(&self) -> bool {
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()
}
fn command(&self) -> String {
ARG_BOOT.to_string()
}
fn to_args(&self) -> Vec<String> {
let mut args = vec![];
if let Some(order) = &self.order {
args.push(format!("{}{}", KEY_ORDER, order.as_ref()));
}
if let Some(once) = &self.once {
args.push(format!("{}{}", KEY_ONCE, once.as_ref()));
}
qao!(&self.menu, args, KEY_MENU);
if let Some(splash) = &self.splash {
args.push(format!("{}{}", KEY_SPLASH, splash.as_ref()));
}
qao!(&self.splash_time, args, KEY_SPLASH_TIME);
qao!(&self.reboot_timeout, args, KEY_REBOOT_TIMEOUT);
qao!(&self.strict, args, KEY_STRICT);
vec![args.join(DELIM_COMMA)]
}
}
impl FromStr for Boot {
type Err = ShellStringError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
boot.parse(s).map_err(|e| ShellStringError::from_parse(e))
}
}
pco0!(order, shell_string_until_comma, ShellString, KEY_ORDER);
pco0!(once, shell_string_until_comma, ShellString, KEY_ONCE);
pco0!(menu, alphanumeric1, OnOff, KEY_MENU);
pco0!(splash, shell_string_until_comma, ShellString, KEY_SPLASH);
ppo0!(splash_time, dec_uint, usize, KEY_SPLASH_TIME);
ppo0!(reboot_timeout, dec_uint, usize, KEY_REBOOT_TIMEOUT);
pco0!(strict, alphanumeric1, OnOff, KEY_STRICT);
pub fn boot(s: &mut &str) -> ModalResult<Boot> {
let order = opt(order).parse_next(s)?;
let once = opt(once).parse_next(s)?;
let menu = opt(menu).parse_next(s)?;
let splash = opt(splash).parse_next(s)?;
let splash_time = opt(splash_time).parse_next(s)?;
let reboot_timeout = opt(reboot_timeout).parse_next(s)?;
let strict = opt(strict).parse_next(s)?;
Ok(Boot {
order,
once,
menu,
splash,
splash_time,
reboot_timeout,
strict,
})
}