rip_rs/
header.rs

1use crate::parser::ParseError;
2use crate::parser::Parsed;
3use crate::serializer::{Serializable, SerializeError};
4use crate::{byte_reader, command, version, zero_bytes};
5
6#[derive(PartialEq, Debug)]
7pub struct Header {
8    command: command::Kind,
9    version: version::Version,
10}
11
12pub fn parse(cursor: usize, bytes: &[u8]) -> Result<Parsed<Header>, ParseError> {
13    let (command, cursor) = command::Kind::parse(cursor, bytes)?;
14    let (version_byte, cursor) = byte_reader::read(cursor, bytes)?;
15    let version_value = version::Version::from_u8(version_byte);
16    let cursor = zero_bytes::skip(2, cursor, bytes)?;
17    let header = Header::new(command, version_value);
18
19    Ok((header, cursor))
20}
21
22impl Header {
23    pub fn new(command: command::Kind, version: version::Version) -> Self {
24        Header { command, version }
25    }
26
27    pub fn get_command(&self) -> command::Kind {
28        self.command
29    }
30
31    pub fn get_version(&self) -> version::Version {
32        self.version
33    }
34}
35
36impl Serializable for Header {
37    fn to_bytes(&self) -> Result<Vec<u8>, SerializeError> {
38        let command_bytes = self.get_command().to_bytes()?;
39        let version_bytes = self.get_version().to_bytes()?;
40        Ok([command_bytes, version_bytes, vec![0, 0]].concat())
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use crate::header::Header;
47    use crate::parser::ParseError;
48    use crate::serializer::Serializable;
49    use crate::{command, header, version};
50
51    #[test]
52    fn test_to_bytes() {
53        assert_eq!(
54            Header::new(command::Kind::Request, version::Version::Version2)
55                .to_bytes()
56                .unwrap(),
57            vec![0x01, 0x02, 0x00, 0x00]
58        );
59    }
60
61    #[test]
62    fn test_parse() {
63        let (header, cursor) = header::parse(0, vec![0x01, 0x02, 0x00, 0x00].as_slice()).unwrap();
64        assert_eq!(
65            header,
66            Header::new(command::Kind::Request, version::Version::Version2)
67        );
68        assert_eq!(cursor, 4);
69    }
70
71    #[test]
72    fn test_parse_has_non_zero_byte() {
73        let err = header::parse(0, vec![0x01, 0x02, 0x01, 0x00].as_slice()).unwrap_err();
74        assert_eq!(err, ParseError::NotZeroByte(0x01, 3));
75
76        let err = header::parse(0, vec![0x01, 0x02, 0x00, 0x02].as_slice()).unwrap_err();
77        assert_eq!(err, ParseError::NotZeroByte(0x02, 4));
78    }
79}