You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.7 KiB
Rust
91 lines
2.7 KiB
Rust
use rlua::{FromLua, Context, Value, Error, ToLua};
|
|
use std::convert::TryFrom;
|
|
|
|
#[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone)]
|
|
pub enum Bind {
|
|
Mouse(u32),
|
|
Key(u32),
|
|
Ping(String),
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Handler {
|
|
pub passthrough: bool,
|
|
pub action: Action,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Action {
|
|
Sync(Bind),
|
|
Press(Bind),
|
|
Release(Bind),
|
|
Sleep(u32),
|
|
List(Vec<Action>),
|
|
}
|
|
|
|
impl<'lua> FromLua<'lua> for Bind {
|
|
fn from_lua(lua_value: Value<'lua>, _: Context<'lua>) -> Result<Self, Error> {
|
|
if let Value::Integer(n) = lua_value {
|
|
return Ok(Bind::Key(u32::try_from(n).map_err(|e| Error::external(e))?));
|
|
}
|
|
|
|
if let Value::String(c) = lua_value {
|
|
return Ok(Bind::Ping(String::from(c.to_str()?)));
|
|
}
|
|
|
|
if let Value::Table(table) = lua_value {
|
|
let typ: String = table.get("type")?;
|
|
let bind = match typ.as_str() {
|
|
"mouse" => Bind::Mouse(table.get("code")?),
|
|
"key" => Bind::Key(table.get("code")?),
|
|
"ping" => Bind::Ping(table.get("code")?),
|
|
_ => return Err(Error::RuntimeError("Type should be one of mouse, key or ping".to_string()))
|
|
};
|
|
|
|
return Ok(bind);
|
|
}
|
|
|
|
Err(Error::RuntimeError("Can't create Bind from non-table".to_string()))
|
|
}
|
|
}
|
|
|
|
impl<'lua> ToLua<'lua> for Bind {
|
|
fn to_lua(self, lua: Context<'lua>) -> Result<Value<'lua>, Error> {
|
|
let table = lua.create_table()?;
|
|
table.set("type", match self {
|
|
Bind::Key(_) => "key",
|
|
Bind::Ping(_) => "ping",
|
|
Bind::Mouse(_) => "mouse",
|
|
})?;
|
|
|
|
match self {
|
|
Bind::Key(n) => table.set("code", n)?,
|
|
Bind::Mouse(n) => table.set("code", n)?,
|
|
Bind::Ping(c) => table.set("code", c)?,
|
|
}
|
|
|
|
Ok(table.to_lua(lua)?)
|
|
}
|
|
}
|
|
|
|
impl<'lua> FromLua<'lua> for Action {
|
|
fn from_lua(lua_value: Value<'lua>, _: Context<'lua>) -> Result<Self, Error> {
|
|
let table = if let Value::Table(table) = lua_value {
|
|
table
|
|
} else {
|
|
return Err(Error::RuntimeError("Action should be a table".to_string()));
|
|
};
|
|
|
|
let res = match table.get::<&str, String>("type")?.as_str() {
|
|
"sync" => Action::Sync(table.get("bind")?),
|
|
"press" => Action::Press(table.get("bind")?),
|
|
"release" => Action::Release(table.get("bind")?),
|
|
"sleep" => Action::Sleep(table.get("time")?),
|
|
"list" => Action::List(table.get("items")?),
|
|
_ => return Err(Error::RuntimeError("Action type is invalid, should be one of sync, release, press, sleep, list".to_string()))
|
|
};
|
|
|
|
Ok(res)
|
|
}
|
|
}
|