Skip to content

Commit 1bdd53f

Browse files
committed
Implement packet encoding and add tests
1 parent 06b1fc2 commit 1bdd53f

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

src/packet.rs

+151
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,47 @@ impl Packet {
137137
Err(ErrorKind::PacketTooLarge.into())
138138
}
139139
}
140+
141+
pub fn to_bytes(&self) -> Result<Vec<u8>> {
142+
let mut buf = Vec::new();
143+
144+
match self {
145+
Packet::Rrq(filename, mode) => {
146+
buf.put_u16_be(RRQ);
147+
buf.put(filename);
148+
buf.put_u8(0);
149+
buf.put(mode.to_str());
150+
buf.put_u8(0);
151+
}
152+
Packet::Wrq(filename, mode) => {
153+
buf.put_u16_be(WRQ);
154+
buf.put(filename);
155+
buf.put_u8(0);
156+
buf.put(mode.to_str());
157+
buf.put_u8(0);
158+
}
159+
Packet::Data(block, data) => {
160+
if data.len() > 512 {
161+
return Err(ErrorKind::PacketTooLarge.into());
162+
}
163+
buf.put_u16_be(DATA);
164+
buf.put_u16_be(*block);
165+
buf.put(data);
166+
}
167+
Packet::Ack(block) => {
168+
buf.put_u16_be(ACK);
169+
buf.put_u16_be(*block);
170+
}
171+
Packet::Error(code, msg) => {
172+
buf.put_u16_be(ERROR);
173+
buf.put_u16_be(*code);
174+
buf.put(msg);
175+
buf.put_u8(0);
176+
}
177+
}
178+
179+
Ok(buf)
180+
}
140181
}
141182

142183
impl Mode {
@@ -161,3 +202,113 @@ impl FromStr for Mode {
161202
}
162203
}
163204
}
205+
206+
#[cfg(test)]
207+
mod tests {
208+
use super::*;
209+
use std::iter::repeat;
210+
211+
#[test]
212+
fn check_rrq() {
213+
let packet = Packet::from_bytes(b"\x00\x01abc\0netascii\0");
214+
assert_eq!(packet, Ok(Packet::Rrq("abc".to_string(), Mode::Netascii)));
215+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x01abc\0netascii\0".to_vec()));
216+
217+
let packet = Packet::from_bytes(b"\x00\x01abc\0netascII\0");
218+
assert_eq!(packet, Ok(Packet::Rrq("abc".to_string(), Mode::Netascii)));
219+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x01abc\0netascii\0".to_vec()));
220+
221+
let packet = Packet::from_bytes(b"\x00\x01abc\0netascii\0more");
222+
assert_eq!(packet, Err(ErrorKind::PacketTooLarge.into()));
223+
224+
let packet = Packet::from_bytes(b"\x00\x01abc\0netascii");
225+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
226+
227+
let packet = Packet::from_bytes(b"\x00\x01abc\0netascXX\0");
228+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
229+
}
230+
231+
#[test]
232+
fn check_wrq() {
233+
let packet = Packet::from_bytes(b"\x00\x02abc\0octet\0");
234+
assert_eq!(packet, Ok(Packet::Wrq("abc".to_string(), Mode::Octet)));
235+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x02abc\0octet\0".to_vec()));
236+
237+
let packet = Packet::from_bytes(b"\x00\x02abc\0OCTet\0");
238+
assert_eq!(packet, Ok(Packet::Wrq("abc".to_string(), Mode::Octet)));
239+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x02abc\0octet\0".to_vec()));
240+
241+
let packet = Packet::from_bytes(b"\x00\x02abc\0octet\0more");
242+
assert_eq!(packet, Err(ErrorKind::PacketTooLarge.into()));
243+
244+
let packet = Packet::from_bytes(b"\x00\x02abc\0octet");
245+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
246+
247+
let packet = Packet::from_bytes(b"\x00\x02abc\0octex\0");
248+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
249+
}
250+
251+
#[test]
252+
fn check_data() {
253+
let packet = Packet::from_bytes(b"\x00\x03\x00\x09abcde");
254+
assert_eq!(packet, Ok(Packet::Data(9, b"abcde".to_vec())));
255+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x03\x00\x09abcde".to_vec()));
256+
257+
let packet = Packet::from_bytes(b"\x00\x03\x00\x09");
258+
assert_eq!(packet, Ok(Packet::Data(9, b"".to_vec())));
259+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x03\x00\x09".to_vec()));
260+
261+
let data: Vec<_> = repeat(b'a').take(512).collect();
262+
let mut packet_vec = b"\x00\x03\x00\x09".to_vec();
263+
packet_vec.extend(data.iter());
264+
265+
let packet = Packet::from_bytes(&packet_vec);
266+
assert_eq!(packet, Ok(Packet::Data(9, data)));
267+
assert_eq!(packet.unwrap().to_bytes(), Ok(packet_vec));
268+
269+
let data: Vec<_> = repeat(b'a').take(513).collect();
270+
let mut packet_vec = b"\x00\x03\x00\x09".to_vec();
271+
packet_vec.extend(data.iter());
272+
273+
let packet = Packet::from_bytes(&packet_vec);
274+
assert_eq!(packet, Err(ErrorKind::PacketTooLarge.into()));
275+
}
276+
277+
#[test]
278+
fn check_ack() {
279+
let packet = Packet::from_bytes(b"\x00\x04\x00\x09");
280+
assert_eq!(packet, Ok(Packet::Ack(9)));
281+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x04\x00\x09".to_vec()));
282+
283+
let packet = Packet::from_bytes(b"\x00\x04\x00");
284+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
285+
286+
let packet = Packet::from_bytes(b"\x00\x04\x00\x09a");
287+
assert_eq!(packet, Err(ErrorKind::PacketTooLarge.into()));
288+
}
289+
290+
#[test]
291+
fn check_error() {
292+
let packet = Packet::from_bytes(b"\x00\x05\x00\x08msg\0");
293+
assert_eq!(packet, Ok(Packet::Error(8, "msg".to_string())));
294+
assert_eq!(packet.unwrap().to_bytes(), Ok(b"\x00\x05\x00\x08msg\0".to_vec()));
295+
296+
let packet = Packet::from_bytes(b"\x00\x05\x00\x08msg\0more");
297+
assert_eq!(packet, Err(ErrorKind::PacketTooLarge.into()));
298+
299+
let packet = Packet::from_bytes(b"\x00\x05\x00\x08msg");
300+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
301+
302+
let packet = Packet::from_bytes(b"\x00\x05\x00\x08");
303+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
304+
}
305+
306+
#[test]
307+
fn check_packet() {
308+
let packet = Packet::from_bytes(b"\x00\x06");
309+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
310+
311+
let packet = Packet::from_bytes(b"\x00\x05\x00");
312+
assert_eq!(packet, Err(ErrorKind::InvalidPacket.into()));
313+
}
314+
}

0 commit comments

Comments
 (0)