jvs_packets/
jvs.rs

1//! A packet structures used for communication with JAMMA Video Standart.
2//!
3//! # Request Packet (master -> slave)
4//!  00     | 01     | 02  | 03       | 04        | ...          | N + 2
5//! :------:|:------:|:---:|:--------:|:---------:|:------------:|:-----:   
6//!  [SYNC] | `DEST` | `N` | `DATA_0` | `DATA_1 ` | `DATA_(N-1)` | `SUM`
7//!  
8//! # Response Packet (slave -> master)
9//!  00     | 01     | 02  | 03       | 04        | 05       | ...          | N + 2
10//! :------:|:------:|:---:|:--------:|:---------:|:--------:|:------------:|:-----:   
11//!  [SYNC] | `DEST` | `N` | [REPORT] | `DATA_0`  | `DATA_1` | `DATA_(N-1)` | `SUM`
12//!
13//! [SYNC]: crate::SYNC_BYTE
14//! [REPORT]: crate::Report
15use std::convert::{AsMut, AsRef};
16
17use crate::{impl_required_packet_blocks, Packet, ReportField};
18
19#[derive(Debug, Clone)]
20pub struct RequestPacket<const N: usize = 256> {
21    inner: [u8; N],
22}
23
24impl<const N: usize> Packet for RequestPacket<N> {
25    const SIZE_INDEX: usize = 2;
26    const DATA_BEGIN_INDEX: usize = 3;
27    const DESTINATION_INDEX: usize = 1;
28}
29
30impl_required_packet_blocks!(RequestPacket);
31
32#[derive(Debug, Clone)]
33pub struct ResponsePacket<const N: usize = 256> {
34    inner: [u8; N],
35}
36
37impl<const N: usize> Packet for ResponsePacket<N> {
38    const SIZE_INDEX: usize = 2;
39    const DATA_BEGIN_INDEX: usize = 4;
40    const DESTINATION_INDEX: usize = 1;
41}
42
43impl<const N: usize> ReportField for ResponsePacket<N> {
44    const REPORT_INDEX: usize = 3;
45}
46
47impl_required_packet_blocks!(ResponsePacket);
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    const REQUEST_DATA: [u8; 6] = [0xE0, 0xFF, 0x03, 0x01, 0x02, 0x05];
54    const RESPONSE_DATA: [u8; 7] = [0xE0, 0xFF, 0x04, 0x01, 0x01, 0x02, 0x07];
55
56    // Request Packet tests
57    #[test]
58    fn test_request_packet_from_slice() {
59        let packet = RequestPacket::<256>::from_slice(&REQUEST_DATA);
60        assert_eq!(REQUEST_DATA, packet.as_slice());
61    }
62
63    #[test]
64    fn test_request_packet_access_methods() {
65        let packet = RequestPacket::<256>::from_slice(&REQUEST_DATA);
66
67        assert_eq!(packet.sync(), REQUEST_DATA[0]);
68        assert_eq!(packet.dest(), REQUEST_DATA[1]);
69        assert_eq!(packet.size(), REQUEST_DATA[2]);
70        assert_eq!(packet.data(), &[REQUEST_DATA[3], REQUEST_DATA[4]]);
71        assert_eq!(packet.checksum(), REQUEST_DATA[5]);
72    }
73
74    #[test]
75    fn test_request_packet_setter_methods() {
76        let mut packet = RequestPacket::<256>::new();
77        packet
78            .set_sync()
79            .set_dest(REQUEST_DATA[1])
80            .set_data(&[REQUEST_DATA[3], REQUEST_DATA[4]])
81            .set_checksum(REQUEST_DATA[5])
82            .set_size(REQUEST_DATA[2]);
83
84        assert_eq!(packet.as_slice(), REQUEST_DATA);
85        packet.calculate_checksum();
86        assert_eq!(packet.checksum(), REQUEST_DATA[5]);
87        packet.set_data(&[0x01]);
88        assert_eq!(packet.size(), REQUEST_DATA[2] - 1);
89    }
90
91    #[test]
92    fn test_request_packet_read() {
93        use crate::ReadPacket;
94        let mut cursor = std::io::Cursor::new(REQUEST_DATA);
95        let mut packet = RequestPacket::<256>::new();
96        cursor.read_packet(&mut packet).unwrap();
97
98        assert_eq!(cursor.into_inner(), packet.as_slice())
99    }
100
101    #[test]
102    fn test_request_packet_write() {
103        use crate::WritePacket;
104        let mut writer = std::io::Cursor::new(vec![]);
105        let packet = RequestPacket::<256>::from_slice(&REQUEST_DATA);
106        writer.write_packet(&packet).unwrap();
107
108        assert_eq!(writer.into_inner(), packet.as_slice())
109    }
110
111    // Response Packet tests
112    #[test]
113    fn test_response_packet_from_slice() {
114        let packet = ResponsePacket::<256>::from_slice(&REQUEST_DATA);
115        assert_eq!(REQUEST_DATA, packet.as_slice());
116    }
117
118    // #[test]
119    // #[should_panic]
120    // fn test_response_packet_from_slice_panic() {
121    //     let data = [0, 1, 2];
122    //     ResponsePacket::<256>::from_slice(&data);
123    // }
124
125    #[test]
126    fn test_response_packet_access_methods() {
127        let packet = dbg!(ResponsePacket::<256>::from_slice(&RESPONSE_DATA));
128
129        assert_eq!(packet.sync(), RESPONSE_DATA[0]);
130        assert_eq!(packet.dest(), RESPONSE_DATA[1]);
131        assert_eq!(packet.size(), RESPONSE_DATA[2]);
132        assert_eq!(packet.report_raw(), RESPONSE_DATA[3]);
133        assert_eq!(packet.data(), &[RESPONSE_DATA[4], RESPONSE_DATA[5]]);
134        assert_eq!(packet.checksum(), RESPONSE_DATA[6]);
135    }
136
137    #[test]
138    fn test_response_packet_setter_methods() {
139        let mut packet = ResponsePacket::<256>::new();
140        packet
141            .set_sync()
142            .set_dest(RESPONSE_DATA[1])
143            .set_report(RESPONSE_DATA[3])
144            .set_data(&[RESPONSE_DATA[4], RESPONSE_DATA[5]])
145            .set_checksum(RESPONSE_DATA[6])
146            .set_size(RESPONSE_DATA[2]);
147
148        assert_eq!(packet.as_slice(), RESPONSE_DATA);
149        packet.calculate_checksum();
150        assert_eq!(packet.checksum(), RESPONSE_DATA[6]);
151        packet.set_data(&[0x01]);
152        assert_eq!(packet.size(), RESPONSE_DATA[2] - 1);
153    }
154
155    #[test]
156    fn test_response_packet_read() {
157        use crate::ReadPacket;
158        let mut reader = std::io::Cursor::new(RESPONSE_DATA);
159        let mut packet = ResponsePacket::<256>::new();
160        reader.read_packet(&mut packet).unwrap();
161
162        assert_eq!(reader.into_inner(), packet.as_slice())
163    }
164
165    #[test]
166    fn test_response_packet_write() {
167        use crate::WritePacket;
168        let mut writer = std::io::Cursor::new(vec![]);
169        let packet = ResponsePacket::<256>::from_slice(&RESPONSE_DATA);
170        writer.write_packet(&packet).unwrap();
171
172        assert_eq!(writer.into_inner(), packet.as_slice())
173    }
174}