use std::num::IntErrorKind;
use teehistorian::chunks::ConsoleCommand;
pub enum Command<'a> {
Team(i32),
ToggleLock,
SetLock(bool),
SaveEmpty,
Save(&'a [u8]),
Load(&'a [u8]),
Kill,
Team0Mode,
Pause,
Spec,
}
impl<'a> Command<'a> {
pub fn serialize(&self) -> String {
match self {
Command::Team(team) => format!("team {team}"),
Command::ToggleLock => "lock".to_string(),
Command::SetLock(lock) => format!("lock {}", *lock as u8),
Command::SaveEmpty => "save".to_string(),
Command::Save(s) => format!("save {}", std::str::from_utf8(s).unwrap()),
Command::Load(s) => format!("load {}", std::str::from_utf8(s).unwrap()),
Command::Kill => "kill".to_string(),
Command::Team0Mode => "team0mode".to_string(),
Command::Pause => "pause".to_string(),
Command::Spec => "spec".to_string(),
}
}
pub fn i32(param: &[u8]) -> i32 {
let _p: i64 = 0;
let param: &str = std::str::from_utf8(param).unwrap_or("0");
match param.parse::<i64>() {
Ok(i) => i as i32,
Err(err) => match err.kind() {
IntErrorKind::PosOverflow => i32::MAX,
IntErrorKind::NegOverflow => 0,
_ => 0,
},
}
}
pub fn from_teehistorian(cmd: &ConsoleCommand<'a>) -> Option<Self> {
match cmd.cmd {
b"team" => {
let arg = cmd.args.first()?;
let arg = std::str::from_utf8(arg).ok()?;
let team = arg.parse::<i32>().ok()?;
Some(Command::Team(team))
}
b"lock" => {
if let Some(arg) = cmd.args.first() {
let i = Command::i32(arg);
Some(Command::SetLock(i != 0))
} else {
Some(Command::ToggleLock)
}
}
b"unlock" => Some(Command::SetLock(false)),
b"load" => cmd.args.first().map(|arg| Command::Load(arg)),
b"save" => {
if let Some(arg) = cmd.args.first() {
Some(Command::Save(arg))
} else {
Some(Command::SaveEmpty)
}
}
b"kill" => Some(Command::Kill),
b"team0mode" => Some(Command::Team0Mode),
b"pause" => Some(Command::Pause),
b"spec" => Some(Command::Spec),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::Command;
#[test]
fn serialize_commands() {
assert_eq!(Command::Team(1).serialize(), "team 1");
assert_eq!(Command::ToggleLock.serialize(), "lock");
assert_eq!(Command::SetLock(true).serialize(), "lock 1");
assert_eq!(Command::SetLock(false).serialize(), "lock 0");
assert_eq!(Command::Kill.serialize(), "kill");
assert_eq!(Command::Pause.serialize(), "pause");
assert_eq!(Command::Spec.serialize(), "spec");
assert_eq!(Command::SaveEmpty.serialize(), "save");
assert_eq!(Command::Save(b"abc").serialize(), "save abc");
assert_eq!(Command::Load(b"123").serialize(), "load 123");
assert_eq!(Command::Load(b"").serialize(), "load ");
assert_eq!(Command::Load(b"abc def").serialize(), "load abc def");
}
}