datagram_connections/
client_to_host.rs

1use crate::{ClientToHostChallengeCommand, ClientToHostCommands};
2use flood_rs::{ReadOctetStream, WriteOctetStream};
3use std::io;
4
5#[repr(u8)]
6pub enum ClientToHostCommand {
7    Challenge = 0x01,
8    Connect = 0x02,
9    Packet = 0x03,
10}
11
12// Implement TryFrom to convert u8 to Command
13impl TryFrom<u8> for ClientToHostCommand {
14    type Error = io::Error;
15
16    fn try_from(value: u8) -> std::io::Result<Self> {
17        match value {
18            0x01 => Ok(ClientToHostCommand::Challenge),
19            0x02 => Ok(ClientToHostCommand::Connect),
20            0x03 => Ok(ClientToHostCommand::Packet),
21            _ => Err(io::Error::new(
22                io::ErrorKind::InvalidData,
23                format!("Unknown command {}", value),
24            )),
25        }
26    }
27}
28
29impl ClientToHostCommands {
30    fn to_octet(&self) -> ClientToHostCommand {
31        match self {
32            ClientToHostCommands::ChallengeType(_) => ClientToHostCommand::Challenge,
33            ClientToHostCommands::ConnectType(_) => ClientToHostCommand::Connect,
34            ClientToHostCommands::PacketType(_) => ClientToHostCommand::Packet,
35        }
36    }
37
38    pub fn to_stream(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
39        stream.write_u8(self.to_octet() as u8)?;
40        match self {
41            ClientToHostCommands::ChallengeType(client_to_host_challenge) => {
42                client_to_host_challenge.to_stream(stream)
43            }
44            ClientToHostCommands::ConnectType(connect_command) => connect_command.to_stream(stream),
45            ClientToHostCommands::PacketType(client_to_host_packet) => {
46                client_to_host_packet.to_stream(stream)
47            }
48        }
49    }
50
51    pub fn from_stream(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
52        let command_value = stream.read_u8()?;
53        let command = ClientToHostCommand::try_from(command_value)?;
54        let x = match command {
55            ClientToHostCommand::Challenge => ClientToHostCommands::ChallengeType(
56                ClientToHostChallengeCommand::from_stream(stream)?,
57            ),
58            _ => {
59                return Err(io::Error::new(
60                    io::ErrorKind::InvalidData,
61                    format!("unknown command {}", command_value),
62                ));
63            }
64        };
65        Ok(x)
66    }
67}