1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::io::{Error, ErrorKind};

pub const MAX_PAYLOAD_SIZE: usize = 16 * 1024 * 1024; // 16MB
#[derive(Debug, Clone, PartialEq)]
pub enum OpCode {
    Continue,
    Text,
    Binary,
    Close,
    Ping,
    Pong,
    // other variants if needed...
}

impl OpCode {
    pub fn from(byte: u8) -> Result<Self, Error> {
        match byte {
            0x0 => Ok(OpCode::Continue),
            0x1 => Ok(OpCode::Text),
            0x2 => Ok(OpCode::Binary),
            0x8 => Ok(OpCode::Close),
            0x9 => Ok(OpCode::Ping),
            0xA => Ok(OpCode::Pong),
            _ => Err(Error::new(ErrorKind::InvalidInput, "Invalid Opcode")),
        }
    }

    pub fn as_u8(&self) -> u8 {
        match self {
            OpCode::Continue => 0x0,
            OpCode::Text => 0x1,
            OpCode::Binary => 0x2,
            OpCode::Close => 0x8,
            OpCode::Ping => 0x9,
            OpCode::Pong => 0xA,
        }
    }

    pub fn is_control(&self) -> bool {
        matches!(self, OpCode::Close | OpCode::Ping | OpCode::Pong)
    }
}

#[derive(Debug, Clone)]
pub struct Frame {
    pub final_fragment: bool,
    pub opcode: OpCode,
    pub payload: Vec<u8>,
}

impl Frame {
    pub fn new(final_fragment: bool, opcode: OpCode, payload: Vec<u8>) -> Self {
        Self {
            final_fragment,
            opcode,
            payload,
        }
    }
}