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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use plain_binary_stream::{Serializable, BinaryStream, PacketType};
use crate::{SerializableSocketAddr};

pub trait PacketHeader<T: PacketType> {
    fn get_type(&self) -> T;
}

pub trait Packet<T: PacketType> : Serializable + PacketHeader<T> {
}

#[derive(Debug, PartialEq)]
pub enum BantamPacketType {
    Handshake = 0,
    HandshakeResponse = 1,
    Data = 2,
    Bye = 3
}

impl PacketType for BantamPacketType {
    fn to_byte(&self) -> u8 {
        match self {
            BantamPacketType::Handshake => 0,
            BantamPacketType::HandshakeResponse => 1,
            BantamPacketType::Data => 2,
            BantamPacketType::Bye => 3
        }
    }

    fn from_byte(byte: u8) -> Option<BantamPacketType> {
        Some(match byte {
            0 => BantamPacketType::Handshake,
            1 => BantamPacketType::HandshakeResponse,
            2 => BantamPacketType::Data,
            3 => BantamPacketType::Bye,
            _ => return None
        })
    }
}

pub struct HandshakePacket {
    pub listening_port: u16,
    pub request_peers: bool
}

pub struct HandshakeResponsePacket {
    pub peers: Vec<SerializableSocketAddr>
}

pub struct DataPacket {
    pub bytes: Vec<u8>
}

pub struct ByePacket {
    pub flag: u8
}

impl Serializable for HandshakePacket {
    fn to_stream(&self, stream: &mut BinaryStream) {
        stream.write_u16(self.listening_port).unwrap();
        stream.write_bool(self.request_peers).unwrap();
    }

    fn from_stream(stream: &mut BinaryStream) -> Self {
        let listening_port = stream.read_u16().unwrap();
        let request_peers = stream.read_bool().unwrap();
        HandshakePacket::new(listening_port, request_peers)
    }
}

impl PacketHeader<BantamPacketType> for HandshakePacket {
    fn get_type(&self) -> BantamPacketType {
        BantamPacketType::Handshake
    }
}

impl HandshakePacket {
    pub fn new(listening_port: u16, request_peers: bool) -> HandshakePacket {
        HandshakePacket {
            listening_port,
            request_peers
        }
    }
}

impl Serializable for HandshakeResponsePacket {
    fn to_stream(&self, stream: &mut BinaryStream) {
        stream.write_vec(&self.peers).unwrap();
    }

    fn from_stream(stream: &mut BinaryStream) -> Self {
        HandshakeResponsePacket {
            peers: stream.read_vec::<SerializableSocketAddr>().unwrap()
        }
    }
}

impl PacketHeader<BantamPacketType> for HandshakeResponsePacket {
    fn get_type(&self) -> BantamPacketType {
        BantamPacketType::HandshakeResponse
    }
}

impl HandshakeResponsePacket {
    pub fn new(peers: Vec<SerializableSocketAddr>) -> HandshakeResponsePacket {
        HandshakeResponsePacket {
            peers
        }
    }
}

impl Serializable for DataPacket {
    fn to_stream(&self, stream: &mut BinaryStream) {
        stream.write_buffer(&self.bytes).unwrap();
    }

    fn from_stream(stream: &mut BinaryStream) -> Self {
        DataPacket::new(stream.read_buffer(stream.size()).unwrap())
    }
}

impl PacketHeader<BantamPacketType> for DataPacket {
    fn get_type(&self) -> BantamPacketType {
        BantamPacketType::Data
    }
}

impl DataPacket {
    pub fn new(bytes: Vec<u8>) -> DataPacket {
        DataPacket {
            bytes
        }
    }
}

impl Serializable for ByePacket {
    fn to_stream(&self, stream: &mut BinaryStream) {
        stream.write_buffer_single(self.flag).unwrap();
    }

    fn from_stream(stream: &mut BinaryStream) -> Self {
        ByePacket::new(stream.read_buffer_single().unwrap())
    }
}

impl PacketHeader<BantamPacketType> for ByePacket {
    fn get_type(&self) -> BantamPacketType {
        BantamPacketType::Bye
    }
}

impl ByePacket {
    pub fn new(flag: u8) -> ByePacket {
        ByePacket {
            flag
        }
    }
}