f1_api/nineteen/
setup.rs

1//! Decoder for car setup packets sent by F1 2019
2//!
3//! The car setup packets by F1 2018 and F1 2019 differ only in their packet headers, the rest of
4//! the packet format is identical.
5
6use std::io::{Cursor, Error};
7
8use bytes::{Buf, BytesMut};
9
10use crate::nineteen::header::decode_header;
11use crate::packet::ensure_packet_size;
12use crate::packet::setup::{CarSetup, CarSetupPacket};
13
14/// Size of the car setups packet in bytes
15pub const PACKET_SIZE: usize = 843;
16
17/// Decode a car setup packet sent by F1 2019
18///
19/// F1 2018 and F1 2019 publish the same data in their car setup packets, but with different packet
20/// headers. In multiplayer sessions, the setups of other players are redacted and appear empty.
21pub fn decode_setups(cursor: &mut Cursor<&mut BytesMut>) -> Result<CarSetupPacket, Error> {
22    ensure_packet_size(PACKET_SIZE, cursor)?;
23
24    let header = decode_header(cursor)?;
25    let mut setups = Vec::with_capacity(20);
26
27    for _ in 0..20 {
28        setups.push(CarSetup::new(
29            cursor.get_u8(),
30            cursor.get_u8(),
31            cursor.get_u8(),
32            cursor.get_u8(),
33            cursor.get_f32_le(),
34            cursor.get_f32_le(),
35            cursor.get_f32_le(),
36            cursor.get_f32_le(),
37            cursor.get_u8(),
38            cursor.get_u8(),
39            cursor.get_u8(),
40            cursor.get_u8(),
41            cursor.get_u8(),
42            cursor.get_u8(),
43            cursor.get_u8(),
44            cursor.get_u8(),
45            cursor.get_f32_le(),
46            cursor.get_f32_le(),
47            cursor.get_u8(),
48            cursor.get_f32_le(),
49        ))
50    }
51
52    Ok(CarSetupPacket::new(header, setups))
53}
54
55#[cfg(test)]
56mod tests {
57    use std::io::Cursor;
58
59    use assert_approx_eq::assert_approx_eq;
60    use bytes::{BufMut, BytesMut};
61
62    use crate::nineteen::setup::{decode_setups, PACKET_SIZE};
63
64    fn put_packet_header(mut bytes: BytesMut) -> BytesMut {
65        bytes.put_u16_le(2019);
66        bytes.put_u8(1);
67        bytes.put_u8(2);
68        bytes.put_u8(3);
69        bytes.put_u8(5);
70        bytes.put_u64_le(u64::max_value());
71        bytes.put_f32_le(1.0);
72        bytes.put_u32_le(u32::max_value());
73        bytes.put_u8(0);
74
75        bytes
76    }
77
78    #[test]
79    fn decode_setups_with_error() {
80        let mut bytes = BytesMut::with_capacity(0);
81        let mut cursor = Cursor::new(&mut bytes);
82
83        let packet = decode_setups(&mut cursor);
84        assert!(packet.is_err());
85    }
86
87    #[test]
88    fn decode_setups_with_success() {
89        let mut bytes = BytesMut::with_capacity(PACKET_SIZE);
90        bytes = put_packet_header(bytes);
91
92        bytes.put_u8(1);
93        bytes.put_u8(2);
94        bytes.put_u8(3);
95        bytes.put_u8(4);
96        bytes.put_f32_le(5.0);
97        bytes.put_f32_le(6.0);
98        bytes.put_f32_le(7.0);
99        bytes.put_f32_le(8.0);
100        bytes.put_u8(9);
101        bytes.put_u8(10);
102        bytes.put_u8(11);
103        bytes.put_u8(12);
104        bytes.put_u8(13);
105        bytes.put_u8(14);
106        bytes.put_u8(15);
107        bytes.put_u8(16);
108        bytes.put_f32_le(17.0);
109        bytes.put_f32_le(18.0);
110        bytes.put_u8(19);
111        bytes.put_f32_le(20.0);
112
113        let padding = vec![0u8; 779];
114        bytes.put(padding.as_slice());
115
116        let mut cursor = Cursor::new(&mut bytes);
117
118        let packet = decode_setups(&mut cursor).unwrap();
119        let setup = packet.setups()[0];
120
121        assert_eq!(1, setup.front_wing());
122        assert_eq!(2, setup.rear_wing());
123        assert_eq!(3, setup.on_throttle());
124        assert_eq!(4, setup.off_throttle());
125        assert_approx_eq!(5.0, setup.front_camber());
126        assert_approx_eq!(6.0, setup.rear_camber());
127        assert_approx_eq!(7.0, setup.front_toe());
128        assert_approx_eq!(8.0, setup.rear_toe());
129        assert_eq!(9, setup.front_suspension());
130        assert_eq!(10, setup.rear_suspension());
131        assert_eq!(11, setup.front_anti_roll_bar());
132        assert_eq!(12, setup.rear_anti_roll_bar());
133        assert_eq!(13, setup.front_suspension_height());
134        assert_eq!(14, setup.rear_suspension_height());
135        assert_eq!(15, setup.brake_pressure());
136        assert_eq!(16, setup.brake_bias());
137        assert_approx_eq!(17.0, setup.front_tyre_pressure());
138        assert_approx_eq!(18.0, setup.rear_tyre_pressure());
139        assert_eq!(19, setup.ballast());
140        assert_approx_eq!(20.0, setup.fuel_load());
141    }
142}