use std::str::FromStr;
#[derive(Clone, Debug, PartialEq)]
pub enum Action {
Cancel(String),
Reschedule(String),
Rm(String),
Unknown(String),
}
crate::control::macros::def_serde_traits_for!(Action);
impl std::fmt::Display for Action {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"{}",
match self {
Self::Cancel(path) => {
format!("cancel {path}")
}
Self::Reschedule(arg) => {
format!("reschedule {arg}")
}
Self::Rm(args) => {
format!("rm {args}")
}
Self::Unknown(unk) => {
unk.clone()
}
}
)
}
}
impl FromStr for Action {
type Err = std::convert::Infallible;
fn from_str(action: &str) -> Result<Self, Self::Err> {
let Ok::<[&str; 2], _>([command, argument]) =
action.splitn(2, ' ').collect::<Vec<_>>().try_into()
else {
return Ok(Self::Unknown(action.to_owned()));
};
Ok(match command {
"cancel" => Self::Cancel(argument.to_owned()),
"rm" => Self::Rm(argument.to_owned()),
"reschedule" => Self::Reschedule(argument.to_owned()),
_ => Self::Unknown(action.to_owned()),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cancel() {
let action: Action = "cancel foo.changes".parse().unwrap();
let Action::Cancel(changes) = action else {
panic!("Not a cancel");
};
assert_eq!("foo.changes", changes);
}
#[test]
fn test_reschedule() {
let action: Action = "reschedule foo.changes 1-day".parse().unwrap();
let Action::Reschedule(arg) = action else {
panic!("Not a reschedule");
};
assert_eq!("foo.changes 1-day", arg);
}
#[test]
fn test_rm() {
let action: Action = "rm --searchdirs foo.changes".parse().unwrap();
let Action::Rm(arg) = action else {
panic!("Not a rm");
};
assert_eq!("--searchdirs foo.changes", arg);
}
#[test]
fn test_unknown() {
let action: Action = "unknown something.changes".parse().unwrap();
let Action::Unknown(args) = action else {
panic!("Not a unknown");
};
assert_eq!("unknown something.changes", args);
}
}