use crate::error::{Error, Result};
use crate::link::Link;
use crate::protocol::opcode::{Q_CAPS, Q_HEALTH, Q_MOUSE_INFO, Q_RATE, Q_STATS, Q_VERSION};
use crate::protocol::{Resp, parse_resp};
use crate::types::{
Button, ButtonAction, Caps, Health, LedMode, LedTarget, MouseInfo, Rate, RebootTarget, Stats,
Version,
};
use super::Device;
#[derive(Clone, Debug)]
pub struct AsyncDevice {
link: Link,
}
impl From<Device> for AsyncDevice {
fn from(device: Device) -> Self {
AsyncDevice { link: device.link }
}
}
impl Device {
pub fn into_async(self) -> AsyncDevice {
AsyncDevice::from(self)
}
}
impl AsyncDevice {
fn dev(&self) -> Device {
Device {
link: self.link.clone(),
}
}
pub fn into_inner(self) -> Device {
Device { link: self.link }
}
pub fn move_rel(&self, dx: i16, dy: i16) -> Result<()> {
self.dev().move_rel(dx, dy)
}
pub fn wheel(&self, delta: i16) -> Result<()> {
self.dev().wheel(delta)
}
pub fn button(&self, button: Button, action: ButtonAction) -> Result<()> {
self.dev().button(button, action)
}
pub fn press(&self, button: Button) -> Result<()> {
self.dev().press(button)
}
pub fn soft_release(&self, button: Button) -> Result<()> {
self.dev().soft_release(button)
}
pub fn force_release(&self, button: Button) -> Result<()> {
self.dev().force_release(button)
}
pub fn reset(&self) -> Result<()> {
self.dev().reset()
}
pub fn reboot(&self, target: RebootTarget) -> Result<()> {
self.dev().reboot(target)
}
pub fn led(&self, target: LedTarget, mode: LedMode, level: u8) -> Result<()> {
self.dev().led(target, mode, level)
}
pub async fn query_version(&self) -> Result<Version> {
let payload = self
.link
.query_async(Q_VERSION, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::Version(v)) => Ok(v),
_ => Err(Error::NoReply),
}
}
pub async fn query_health(&self) -> Result<Health> {
let payload = self
.link
.query_async(Q_HEALTH, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::Health(h)) => Ok(h),
_ => Err(Error::NoReply),
}
}
pub async fn query_mouse_info(&self) -> Result<MouseInfo> {
let payload = self
.link
.query_async(Q_MOUSE_INFO, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::MouseInfo(m)) => Ok(m),
_ => Err(Error::NoReply),
}
}
pub async fn query_caps(&self) -> Result<Caps> {
let payload = self
.link
.query_async(Q_CAPS, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::Caps(c)) => Ok(c),
_ => Err(Error::NoReply),
}
}
pub async fn query_rate(&self) -> Result<Rate> {
let payload = self
.link
.query_async(Q_RATE, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::Rate(r)) => Ok(r),
_ => Err(Error::NoReply),
}
}
pub async fn query_stats(&self) -> Result<Stats> {
let payload = self
.link
.query_async(Q_STATS, self.link.query_timeout_default())
.await?;
match parse_resp(&payload) {
Some(Resp::Stats(s)) => Ok(s),
_ => Err(Error::NoReply),
}
}
pub fn open(path: impl AsRef<std::path::Path>) -> Result<AsyncDevice> {
Ok(Device::open(path)?.into_async())
}
}