use anyhow::Result;
use mist_core::{config::KeybindsRaw, error::MistError::Str};
use sdl2::keyboard::Keycode;
use sdl2::mouse::MouseButton;
#[derive(Debug, PartialEq)]
pub enum Binding {
Key(Keycode),
Mouse(MouseButton),
}
impl From<Keycode> for Binding {
fn from(a: Keycode) -> Binding {
Binding::Key(a)
}
}
impl From<MouseButton> for Binding {
fn from(a: MouseButton) -> Binding {
Binding::Mouse(a)
}
}
#[derive(Debug)]
pub struct Keybinds {
pub pause: Binding,
pub reset: Binding,
pub start_split: Binding,
pub skip_split: Binding,
pub un_split: Binding,
pub prev_comp: Binding,
pub next_comp: Binding,
pub load_splits: Binding,
pub load_config: Binding,
pub dump_state: Binding,
pub load_state: Binding,
}
impl Keybinds {
pub fn from_raw(raw: &KeybindsRaw) -> Result<Self> {
Ok(Keybinds {
pause: Keycode::from_name(&raw.pause)
.map(|key| key.into())
.or(parse_mouse(&raw.pause))
.ok_or(Str("Pause keybind could not be parsed.".into()))?,
reset: Keycode::from_name(&raw.reset)
.map(|key| key.into())
.or(parse_mouse(&raw.reset))
.ok_or(Str("Reset keybind could not be parsed.".into()))?,
start_split: Keycode::from_name(&raw.start_split)
.map(|key| key.into())
.or(parse_mouse(&raw.start_split))
.ok_or(Str("start/split keybind could not be parsed.".into()))?,
skip_split: Keycode::from_name(&raw.skip_split)
.map(|key| key.into())
.or(parse_mouse(&raw.skip_split))
.ok_or(Str("Skip split keybind could not be parsed".into()))?,
un_split: Keycode::from_name(&raw.un_split)
.map(|key| key.into())
.or(parse_mouse(&raw.un_split))
.ok_or(Str("Unsplit keybind could not be parsed".into()))?,
prev_comp: Keycode::from_name(&raw.prev_comp)
.map(|key| key.into())
.or(parse_mouse(&raw.prev_comp))
.ok_or(Str("Prev comparison keybind could not be parsed".into()))?,
next_comp: Keycode::from_name(&raw.next_comp)
.map(|key| key.into())
.or(parse_mouse(&raw.next_comp))
.ok_or(Str("Next comparison keybind could not be parsed".into()))?,
load_splits: Keycode::from_name(&raw.load_splits)
.map(|key| key.into())
.or(parse_mouse(&raw.load_splits))
.ok_or(Str("Load splits keybind could not be parsed".into()))?,
load_config: Keycode::from_name(&raw.load_config)
.map(|key| key.into())
.or(parse_mouse(&raw.load_config))
.ok_or(Str("Load config keybind could not be parsed".into()))?,
dump_state: Keycode::from_name(&raw.dump_state)
.map(|key| key.into())
.or(parse_mouse(&raw.dump_state))
.ok_or(Str("Dump state keybind could not be parsed".into()))?,
load_state: Keycode::from_name(&raw.load_state)
.map(|key| key.into())
.or(parse_mouse(&raw.load_state))
.ok_or(Str("Load state keybind could not be parsed".into()))?,
})
}
}
fn parse_mouse(i: &str) -> Option<Binding> {
match i {
"LeftMouse" => Some(MouseButton::Left.into()),
"RightMouse" => Some(MouseButton::Right.into()),
"MiddleMouse" => Some(MouseButton::Middle.into()),
"X1" => Some(MouseButton::X1.into()),
"X2" => Some(MouseButton::X2.into()),
_ => None,
}
}