use crate::keycodes;
use crate::protocol::{
CMD_VIA_VIAL_PREFIX, CMD_VIAL_GET_ENCODER, CMD_VIAL_SET_ENCODER, ProtocolError, send_recv,
};
use anyhow::{Result, anyhow};
use hidapi::HidDevice;
use serde_json::{Value, json};
#[derive(Debug)]
pub struct Encoder {
pub index: u8,
pub ccw: u16,
pub cw: u16,
}
pub fn load_encoder(device: &HidDevice, layer: u8, index: u8) -> Result<Encoder> {
match send_recv(
device,
&[CMD_VIA_VIAL_PREFIX, CMD_VIAL_GET_ENCODER, layer, index],
) {
Ok(data) => Ok(Encoder {
index,
ccw: ((data[0] as u16) << 8) + (data[1] as u16),
cw: ((data[2] as u16) << 8) + (data[3] as u16),
}),
Err(e) => Err(e),
}
}
pub fn set_encoder(
device: &HidDevice,
layer: u8,
index: u8,
direction: u8,
value: u16,
) -> Result<()> {
match send_recv(
device,
&[
CMD_VIA_VIAL_PREFIX,
CMD_VIAL_SET_ENCODER,
layer,
index,
direction,
(value >> 8) as u8,
(value & 0xFF) as u8,
],
) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
pub fn load_encoders_from_json(
encoders_json: &Value,
vial_version: u32,
) -> Result<Vec<Vec<Encoder>>> {
let mut result = Vec::new();
if matches!(encoders_json, Value::Null) {
return Ok(result);
}
let layers = encoders_json.as_array().ok_or(anyhow!(
"encoders should be encoded as array of arrays of arrays"
))?;
for layer in layers {
let mut layer_encoders = Vec::new();
for (idx, encoder) in layer
.as_array()
.ok_or(anyhow!(
"encoders should be encoded as array of arrays of arrays"
))?
.iter()
.enumerate()
{
let values = encoder.as_array().ok_or(anyhow!(
"encoder values should be and array with two elements"
))?;
if values.len() != 2 {
return Err(ProtocolError::General(
"encoder values should be and array with two elements".to_string(),
)
.into());
}
let ccw = values[0]
.as_str()
.ok_or(anyhow!("encoder value should be a string"))?;
let ccw = keycodes::name_to_qid(ccw, vial_version)?;
let cw = values[1]
.as_str()
.ok_or(anyhow!("encoder value should be a string"))?;
let cw = keycodes::name_to_qid(cw, vial_version)?;
layer_encoders.push(Encoder {
index: idx as u8,
ccw,
cw,
});
}
result.push(layer_encoders);
}
Ok(result)
}
pub fn encoders_to_json(
layers_encoders: &Vec<Vec<Encoder>>,
vial_version: u32,
) -> Result<Vec<Value>> {
let mut result = Vec::new();
for layer_encoder in layers_encoders {
let mut layer = Vec::new();
for encoder in layer_encoder {
layer.push(json!([
keycodes::qid_to_name(encoder.ccw, vial_version),
keycodes::qid_to_name(encoder.cw, vial_version),
]))
}
result.push(Value::Array(layer));
}
Ok(result)
}