use crate::constants::{TYPE_ERROR, TYPE_PASSTHROUGH_ERROR, TYPE_RESPONSE};
use crate::error::{EmapiError, Result};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EmapiCommand {
pub command_type: u8,
pub parent: u8,
pub child: u8,
pub payload: Vec<u8>,
}
impl EmapiCommand {
pub fn new(command_type: u8, parent: u8, child: u8, payload: impl Into<Vec<u8>>) -> Self {
Self {
command_type,
parent,
child,
payload: payload.into(),
}
}
pub fn try_new(
command_type: u16,
parent: u16,
child: u16,
payload: impl Into<Vec<u8>>,
) -> Result<Self> {
Ok(Self::new(
check_byte(command_type, "type")?,
check_byte(parent, "parent")?,
check_byte(child, "child")?,
payload,
))
}
pub fn is_ack_for(&self, parent: u8, child: u8) -> bool {
self.is_response_for(TYPE_RESPONSE, parent, child) && self.payload.is_empty()
}
pub fn is_response_for(&self, command_type: u8, parent: u8, child: u8) -> bool {
self.command_type == command_type && self.parent == parent && self.child == child
}
pub fn is_error(&self) -> bool {
self.command_type == TYPE_ERROR || self.command_type == TYPE_PASSTHROUGH_ERROR
}
pub fn is_protocol_error(&self) -> bool {
self.command_type == TYPE_ERROR
}
pub fn is_passthrough_error(&self) -> bool {
self.command_type == TYPE_PASSTHROUGH_ERROR
}
}
fn check_byte(value: u16, name: &'static str) -> Result<u8> {
if value > 0xFF {
return Err(EmapiError::Range {
name,
min: 0,
max: 0xFF,
value: u64::from(value),
});
}
Ok(value as u8)
}