nardol 0.0.3

Simple framework that provides structure to data sent and received from network.
Documentation
use serde::{Deserialize, Serialize};

use crate::bytes::Bytes;
use crate::error::{Error, ErrorKind};
use crate::ron::{FromRon, ToRon};

/// Determines kind of [Packet](super::Packet).
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PacketKind {
    /// Empty packet usually used only for testing or like a placeholder.
    Empty,

    /// Part of `metadata`.
    MetaData,

    /// Same as [MetaData](PacketKind::MetaData), only marking end of it.
    MetaDataEnd,

    /// Content packet.
    Content,

    /// Used to signalize end of the [`message`].
    ///
    /// Can be [TcpMessage](crate::message::TcpMessage)
    /// or an end in general (of all times and you know it).
    End,

    /// Usually used in udp context for signaling that given [Packet](super::Packet)
    /// is the whole `message`.
    Unit,

    /// Used in case if [PacketKind] is not recognized.
    Unknown,
}

impl ToRon for PacketKind {}
impl FromRon<'_> for PacketKind {}

impl TryFrom<Bytes> for PacketKind {
    type Error = Error;

    fn try_from(value: Bytes) -> Result<Self, Self::Error> {
        // Checks if value has enough bytes to parse to PacketKind (at least 2).
        match value.get(1) {
            Some(_) => &value[0..2],
            None => {
                return Err(Error::new(
                    ErrorKind::InvalidBufferSize,
                    Some(
                        concat!(
                            "impl TryFrom<Bytes> for PacketKind requires buffer of length",
                            "of at least 2 bytes.",
                        )
                        .to_string(),
                    ),
                ))
            }
        };

        let kind = match value[0] {
            0 => PacketKind::Empty,
            1 => match value[1] {
                0 => PacketKind::MetaData,
                1 => PacketKind::MetaDataEnd,
                _ => PacketKind::Unknown,
            },
            2 => PacketKind::Content,
            3 => PacketKind::End,
            4 => PacketKind::Unit,
            _ => PacketKind::Unknown,
        };

        Ok(kind)
    }
}

impl TryFrom<&[u8]> for PacketKind {
    type Error = Error;

    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
        // Checks if value has enough bytes to parse to PacketKind (at least 2).
        match value.get(1) {
            Some(_) => &value[0..2],
            None => {
                return Err(Error::new(
                    ErrorKind::InvalidBufferSize,
                    Some(
                        concat!(
                            "impl TryFrom<&[u8]> for PacketKind requires buffer of length",
                            "of at least 2 bytes.",
                        )
                        .to_string(),
                    ),
                ))
            }
        };

        let kind = match value[0] {
            0 => PacketKind::Empty,
            1 => match value[1] {
                0 => PacketKind::MetaData,
                1 => PacketKind::MetaDataEnd,
                _ => PacketKind::Unknown,
            },
            2 => PacketKind::Content,
            3 => PacketKind::End,
            4 => PacketKind::Unit,
            _ => PacketKind::Unknown,
        };

        Ok(kind)
    }
}

impl From<PacketKind> for Bytes {
    fn from(value: PacketKind) -> Self {
        let mut bytes = Bytes::empty();

        match value {
            PacketKind::Empty => bytes.append(&mut Bytes::from([0, 0])),
            PacketKind::MetaData => bytes.append(&mut Bytes::from([1, 0])),
            PacketKind::MetaDataEnd => bytes.append(&mut Bytes::from([1, 1])),
            PacketKind::Content => bytes.append(&mut Bytes::from([2, 0])),
            PacketKind::End => bytes.append(&mut Bytes::from([3, 0])),
            PacketKind::Unit => bytes.append(&mut Bytes::from([4, 0])),
            PacketKind::Unknown => bytes.append(&mut Bytes::from([255, 0])),
        }

        bytes
    }
}