From cd3282a69d2e7fc5f5bb15d8023c3ff314f71adc Mon Sep 17 00:00:00 2001
From: clerie <git@clerie.de>
Date: Wed, 18 Dec 2024 21:20:00 +0100
Subject: [PATCH] Convert to error states

---
 src/improv.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/main.rs   |  4 ++++
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/improv.rs b/src/improv.rs
index 0cfc8a3..cb04bd1 100644
--- a/src/improv.rs
+++ b/src/improv.rs
@@ -85,6 +85,33 @@ pub enum ErrorState {
     UnknownError = 0xFF,
 }
 
+impl TryFrom<&u8> for ErrorState {
+    type Error= &'static str;
+
+    fn try_from(b: &u8) -> Result<Self, Self::Error> {
+        match b {
+            0x00 => Ok(Self::NoError),
+            0x01 => Ok(Self::InvalidRPCPacket),
+            0x02 => Ok(Self::UnknownRPCCommand),
+            0x03 => Ok(Self::UnableToConnect),
+            0x04 => Ok(Self::UnknownError),
+            _ => Err("Cannot convert to error type"),
+        }
+    }
+}
+
+impl std::fmt::Display for ErrorState {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::NoError => write!(f, "No Error"),
+            Self::InvalidRPCPacket => write!(f, "Invalid RPC Packet"),
+            Self::UnknownRPCCommand => write!(f, "Unknown RPC Command"),
+            Self::UnableToConnect => write!(f, "Unable To Connect"),
+            Self::UnknownError => write!(f, "Unknown Error"),
+        }
+    }
+}
+
 #[derive(Clone)]
 #[repr(u8)]
 pub enum RPCCommand {
@@ -187,6 +214,7 @@ impl RawPacket {
 
 pub enum ImprovPacket {
     CurrentStateResponse(CurrentStateResponse),
+    ErrorState(ErrorStatePacket),
     RequestCurrentStateCommand(RequestCurrentStateCommand),
 }
 
@@ -194,7 +222,7 @@ impl ImprovPacket {
     pub fn try_from_raw_packet(raw_packet: &RawPacket) -> Result<Self, &str> {
         match raw_packet.r#type {
             PacketType::CurrentState => Ok(ImprovPacket::CurrentStateResponse(CurrentStateResponse::try_from_raw_packet(raw_packet)?)),
-            //PacketType::ErrorState => _,
+            PacketType::ErrorState => Ok(ImprovPacket::ErrorState(ErrorStatePacket::try_from_raw_packet(raw_packet)?)),
             //PacketType::RPCCommand => _,
             //PacketType::RPCResult => _,
             _ => Err("Conversion into packet type {} not implemented"),
@@ -232,6 +260,28 @@ impl ImprovDataFromPacket for CurrentStateResponse {
     }
 }
 
+pub struct ErrorStatePacket {
+    pub error_state: ErrorState,
+}
+
+impl ImprovDataPacketType for ErrorStatePacket {
+    const packet_type: PacketType = PacketType::ErrorState;
+}
+
+impl ImprovDataFromPacket for ErrorStatePacket {
+    type Error = &'static str;
+
+    fn try_from_raw_packet(raw_packet: &RawPacket) -> Result<Self, Self::Error>{
+        if raw_packet.r#type != Self::packet_type {
+            return Err("Packet is not ErrorState");
+        }
+
+        return Ok(Self {
+            error_state: ErrorState::try_from(&raw_packet.data[0])?,
+        })
+    }
+}
+
 pub struct RequestCurrentStateCommand {
 }
 
diff --git a/src/main.rs b/src/main.rs
index 613eaee..62f23f9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -152,6 +152,10 @@ async fn main() -> Result<()>{
                 println!("Current state: {}", &current_state_response.current_state);
             }
 
+            if let ImprovPacket::ErrorState(error_state) = ImprovPacket::try_from_raw_packet(&raw_packet).unwrap() {
+                println!("Error state: {}", &error_state.error_state);
+            }
+
         },
     };