1use std::io::{Cursor, Error, ErrorKind};
7use std::time::Duration;
8
9use bytes::{Buf, BytesMut};
10
11use crate::nineteen::header::decode_header;
12use crate::packet::ensure_packet_size;
13use crate::packet::lap::{DriverStatus, Lap, LapPacket, PitStatus, ResultStatus, Sector};
14
15pub const PACKET_SIZE: usize = 843;
17
18pub fn decode_lap_data(cursor: &mut Cursor<&mut BytesMut>) -> Result<LapPacket, Error> {
23 ensure_packet_size(PACKET_SIZE, cursor)?;
24
25 let header = decode_header(cursor)?;
26 let mut laps = Vec::with_capacity(20);
27
28 for _ in 0..20 {
29 laps.push(Lap::new(
30 Duration::from_secs_f32(cursor.get_f32_le()),
31 Duration::from_secs_f32(cursor.get_f32_le()),
32 Duration::from_secs_f32(cursor.get_f32_le()),
33 Duration::from_secs_f32(cursor.get_f32_le()),
34 Duration::from_secs_f32(cursor.get_f32_le()),
35 cursor.get_f32_le(),
36 cursor.get_f32_le(),
37 Duration::from_secs_f32(cursor.get_f32_le()),
38 cursor.get_u8(),
39 cursor.get_u8(),
40 decode_pit_status(cursor)?,
41 decode_sector(cursor)?,
42 cursor.get_u8() < 1,
43 cursor.get_u8(),
44 cursor.get_u8(),
45 decode_driver_status(cursor)?,
46 decode_result_status(cursor)?,
47 ));
48 }
49
50 Ok(LapPacket::new(header, laps))
51}
52
53fn decode_sector(cursor: &mut Cursor<&mut BytesMut>) -> Result<Sector, Error> {
54 let value = cursor.get_u8();
55
56 match value {
57 0 => Ok(Sector::First),
58 1 => Ok(Sector::Second),
59 2 => Ok(Sector::Third),
60 _ => Err(Error::new(
61 ErrorKind::InvalidData,
62 "Failed to decode sector.",
63 )),
64 }
65}
66
67fn decode_pit_status(cursor: &mut Cursor<&mut BytesMut>) -> Result<PitStatus, Error> {
68 let value = cursor.get_u8();
69
70 match value {
71 0 => Ok(PitStatus::None),
72 1 => Ok(PitStatus::Pitting),
73 2 => Ok(PitStatus::InPits),
74 _ => Err(Error::new(
75 ErrorKind::InvalidData,
76 "Failed to decode pit status.",
77 )),
78 }
79}
80
81fn decode_driver_status(cursor: &mut Cursor<&mut BytesMut>) -> Result<DriverStatus, Error> {
82 let value = cursor.get_u8();
83
84 match value {
85 0 => Ok(DriverStatus::InGarage),
86 1 => Ok(DriverStatus::FlyingLap),
87 2 => Ok(DriverStatus::InLap),
88 3 => Ok(DriverStatus::OutLap),
89 4 => Ok(DriverStatus::OnTrack),
90 _ => Err(Error::new(
91 ErrorKind::InvalidData,
92 "Failed to decode driver status.",
93 )),
94 }
95}
96
97fn decode_result_status(cursor: &mut Cursor<&mut BytesMut>) -> Result<ResultStatus, Error> {
98 let value = cursor.get_u8();
99
100 match value {
101 0 => Ok(ResultStatus::Invalid),
102 1 => Ok(ResultStatus::Inactive),
103 2 => Ok(ResultStatus::Active),
104 3 => Ok(ResultStatus::Finished),
105 4 => Ok(ResultStatus::Disqualified),
106 5 => Ok(ResultStatus::NotClassified),
107 6 => Ok(ResultStatus::Retired),
108 _ => Err(Error::new(
109 ErrorKind::InvalidData,
110 "Failed to decode result status.",
111 )),
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use std::io::Cursor;
118
119 use bytes::{BufMut, BytesMut};
120
121 use crate::nineteen::lap::{decode_lap_data, PACKET_SIZE};
122 use crate::packet::lap::{DriverStatus, PitStatus, ResultStatus, Sector};
123
124 fn put_packet_header(mut bytes: BytesMut) -> BytesMut {
125 bytes.put_u16_le(2019);
126 bytes.put_u8(1);
127 bytes.put_u8(2);
128 bytes.put_u8(3);
129 bytes.put_u8(0);
130 bytes.put_u64_le(u64::max_value());
131 bytes.put_f32_le(1.0);
132 bytes.put_u32_le(u32::max_value());
133 bytes.put_u8(0);
134
135 bytes
136 }
137
138 #[test]
139 fn decode_lap_data_with_error() {
140 let mut bytes = BytesMut::with_capacity(0);
141 let mut cursor = Cursor::new(&mut bytes);
142
143 let packet = decode_lap_data(&mut cursor);
144 assert!(packet.is_err());
145 }
146
147 #[test]
148 fn decode_lap_data_with_success() {
149 let mut bytes = BytesMut::with_capacity(PACKET_SIZE);
150 bytes = put_packet_header(bytes);
151
152 bytes.put_f32_le(62.0);
153 bytes.put_f32_le(60.0);
154 bytes.put_f32_le(58.1);
155 bytes.put_f32_le(21.1);
156 bytes.put_f32_le(19.0);
157 bytes.put_f32_le(543.0);
158 bytes.put_f32_le(2048.4);
159 bytes.put_f32_le(0.0);
160 bytes.put_u8(1);
161 bytes.put_u8(4);
162 bytes.put_u8(0);
163 bytes.put_u8(2);
164 bytes.put_u8(0);
165 bytes.put_u8(0);
166 bytes.put_u8(3);
167 bytes.put_u8(1);
168 bytes.put_u8(2);
169
170 let padding = vec![0u8; 779];
171 bytes.put(padding.as_slice());
172
173 let mut cursor = Cursor::new(&mut bytes);
174
175 let packet = decode_lap_data(&mut cursor).unwrap();
176 let lap = packet.laps()[0];
177
178 assert_eq!(62, lap.last_lap_time().as_secs());
179 assert_eq!(60, lap.current_lap_time().as_secs());
180 assert_eq!(58, lap.best_lap_time().as_secs());
181 assert_eq!(21, lap.sector1_time().as_secs());
182 assert_eq!(19, lap.sector2_time().as_secs());
183 assert_eq!(543, lap.lap_distance() as usize);
184 assert_eq!(2048, lap.total_distance() as usize);
185 assert_eq!(0, lap.safety_car_delta().as_secs());
186 assert_eq!(1, lap.position());
187 assert_eq!(4, lap.current_lap_number());
188 assert_eq!(PitStatus::None, lap.pit_status());
189 assert_eq!(Sector::Third, lap.sector());
190 assert!(lap.is_valid_lap());
191 assert_eq!(0, lap.penalties());
192 assert_eq!(3, lap.grid_position());
193 assert_eq!(DriverStatus::FlyingLap, lap.driver_status());
194 assert_eq!(ResultStatus::Active, lap.result_status())
195 }
196}