use crate::ButtonEvent;
#[non_exhaustive]
pub enum HostEvent {
Exit,
Button(ButtonEvent),
FinishedAudio(u64),
Timeout,
}
impl HostEvent {
fn event_type_u8(&self) -> u8 {
match self {
Self::Exit => 0,
Self::Button(_) => 1,
Self::FinishedAudio(_) => 2,
Self::Timeout => 3,
}
}
fn payload(&self) -> [u8; 7] {
let mut result = [0u8; 7];
match self {
Self::Button(b) => result[5..7].copy_from_slice(&b.as_u16().to_le_bytes()),
Self::Exit => {}
Self::FinishedAudio(controller_id) => {
result.copy_from_slice(&controller_id.to_le_bytes()[0..7]);
}
Self::Timeout => {}
}
result
}
}
impl TryFrom<i64> for HostEvent {
type Error = u8;
fn try_from(value: i64) -> Result<Self, Self::Error> {
let buffer = value.to_le_bytes();
let event_type = buffer[0];
match event_type {
0 => Ok(Self::Exit),
1 => {
let mut u16_buffer = [0u8; 2];
u16_buffer.copy_from_slice(&buffer[6..8]);
Ok(Self::Button(ButtonEvent::from_u16(u16::from_le_bytes(
u16_buffer,
))))
}
2 => {
let mut u64_buffer = [0u8; 8];
u64_buffer[0..7].copy_from_slice(&buffer[1..8]);
let controller_id = u64::from_le_bytes(u64_buffer);
Ok(Self::FinishedAudio(controller_id))
}
3 => Ok(Self::Timeout),
n => Err(n),
}
}
}
impl From<&HostEvent> for i64 {
fn from(value: &HostEvent) -> Self {
let event_type_u8 = value.event_type_u8();
let payload = value.payload();
let mut buffer = [0u8; 8];
buffer[0] = event_type_u8;
buffer[1..].copy_from_slice(&payload);
i64::from_le_bytes(buffer)
}
}
impl From<HostEvent> for i64 {
fn from(value: HostEvent) -> Self {
i64::from(&value)
}
}