nimble_step/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/nimble-rust/nimble
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use flood_rs::prelude::*;
7use std::fmt::{Display, Formatter};
8use std::io;
9use tick_id::TickId;
10
11#[derive(Debug, Clone, Eq, PartialEq)]
12pub struct JoinedData {
13    pub tick_id: TickId,
14}
15
16impl Serialize for JoinedData {
17    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
18        stream.write_u32(self.tick_id.0)
19    }
20}
21
22impl Deserialize for JoinedData {
23    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
24        Ok(Self {
25            tick_id: TickId(stream.read_u32()?),
26        })
27    }
28}
29
30#[derive(Debug, Clone, Eq, PartialEq)] // Clone is needed since it can be in collections (like pending steps queue), Eq and PartialEq is to be able to use in tests, Debug for debug output.
31pub enum Step<T> {
32    Forced,
33    WaitingForReconnect,
34    Joined(JoinedData),
35    Left,
36    Custom(T),
37}
38
39impl<T> Step<T> {
40    #[must_use]
41    pub const fn to_octet(&self) -> u8 {
42        match self {
43            Self::Forced => 0x01,
44            Self::WaitingForReconnect => 0x02,
45            Self::Joined(_) => 0x03,
46            Self::Left => 0x04,
47            Self::Custom(_) => 0x05,
48        }
49    }
50}
51
52impl<T: Display> Display for Step<T> {
53    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54        match self {
55            Self::Forced => write!(f, "Forced"),
56            Self::WaitingForReconnect => write!(f, "Forced"),
57            Self::Joined(join_data) => write!(f, "joined {join_data:?}"),
58            Self::Left => write!(f, "Left"),
59            Self::Custom(custom) => write!(f, "Custom({})", custom),
60        }
61    }
62}
63
64impl<T: Serialize> Serialize for Step<T> {
65    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
66        stream.write_u8(self.to_octet())?;
67        match self {
68            Self::Joined(join) => join.serialize(stream),
69            Self::Custom(custom) => custom.serialize(stream),
70            _ => Ok(()),
71        }
72    }
73}
74
75impl<T: Deserialize> Deserialize for Step<T> {
76    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
77        let step_type = stream.read_u8()?;
78        let t = match step_type {
79            0x01 => Self::Forced,
80            0x02 => Self::WaitingForReconnect,
81            0x03 => Self::Joined(JoinedData::deserialize(stream)?),
82            0x04 => Self::Left,
83            0x05 => Self::Custom(T::deserialize(stream)?),
84            _ => Err(io::Error::new(
85                io::ErrorKind::InvalidInput,
86                "invalid input, unknown step type",
87            ))?,
88        };
89        Ok(t)
90    }
91}