f1_api/packet/event.rs
1//! Events that can occur during the course of a session
2//!
3//! The F1 games send event packets whenever certain events occur in a session. _F1 2018_ defined
4//! only two events, but _F1 2019_ extended this to nine different events. Some events carry a
5//! payload that further defines the event, and that are declared in this module as structs.
6
7use std::fmt;
8use std::fmt::Display;
9use std::time::Duration;
10
11use derive_new::new;
12use getset::{CopyGetters, Getters};
13
14use crate::packet::header::Header;
15use crate::types::VehicleIndex;
16
17/// Payload for fastest lap event
18///
19/// The fastest lap event contains the driver achieving the fastest lap as well as the lap time as
20/// its payload. The driver is referenced through the vehicle index, while the lap time is provided
21/// in seconds.
22///
23/// # Examples
24///
25/// ```
26/// # use f1_api::packet::event::{FastestLap, Event};
27/// # use std::time::Duration;
28/// #
29/// # let fastest_lap = FastestLap::new(0, Duration::from_secs(62));
30/// # let event = Event::FastestLap(fastest_lap);
31/// #
32/// // Simplified use in a match statement
33/// match event {
34/// Event::FastestLap(lap) => {
35/// assert_eq!(0, lap.vehicle_index());
36/// assert_eq!(62, lap.time().as_secs());
37/// }
38/// # _ => panic!("Example should never fail")
39/// }
40/// ```
41#[derive(
42 new, Debug, Getters, CopyGetters, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash, Default,
43)]
44pub struct FastestLap {
45 /// Returns the index of the car achieving the fastest lap.
46 #[getset(get_copy = "pub")]
47 vehicle_index: VehicleIndex,
48
49 /// Returns the time of the fastest lap.
50 #[getset(get = "pub")]
51 time: Duration,
52}
53
54impl Display for FastestLap {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(
57 f,
58 "{}s by car #{}",
59 self.time.as_secs_f32(),
60 self.vehicle_index
61 )
62 }
63}
64
65/// Payload for retirement event
66///
67/// The retirement event contains the vehicle index of the retired driver as its payload.
68///
69/// # Examples
70///
71/// ```
72/// # use f1_api::packet::event::{Event, Retirement};
73/// #
74/// # let retirement = Retirement::new(0);
75/// # let event = Event::Retirement(retirement);
76/// #
77/// // Simplified use in a match statement
78/// match event {
79/// Event::Retirement(retirement) => {
80/// assert_eq!(0, retirement.vehicle_index());
81/// }
82/// # _ => panic!("Example should never fail")
83/// }
84/// ```
85#[derive(
86 new, Debug, Getters, CopyGetters, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash, Default,
87)]
88pub struct Retirement {
89 /// Returns the index of the car retiring.
90 #[getset(get_copy = "pub")]
91 vehicle_index: VehicleIndex,
92}
93
94impl Display for Retirement {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "retirement of car #{}", self.vehicle_index)
97 }
98}
99
100/// Payload for teammate in pits event
101///
102/// When a teammate enters the pits, an event is sent carrying the vehicle index of the teammate as
103/// its payload.
104///
105/// # Examples
106///
107/// ```
108/// # use f1_api::packet::event::{Event, TeammateInPits};
109/// #
110/// # let teammate_in_pits = TeammateInPits::new(0);
111/// # let event = Event::TeammatesInPits(teammate_in_pits);
112/// #
113/// // Simplified use in a match statement
114/// match event {
115/// Event::TeammatesInPits(teammate) => {
116/// assert_eq!(0, teammate.vehicle_index());
117/// }
118/// # _ => panic!("Example should never fail")
119/// }
120/// ```
121#[derive(
122 new, Debug, Getters, CopyGetters, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash, Default,
123)]
124pub struct TeammateInPits {
125 /// Returns the index of the teammate who has just entered the pits.
126 #[getset(get_copy = "pub")]
127 vehicle_index: VehicleIndex,
128}
129
130impl Display for TeammateInPits {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 write!(f, "teammate in car #{} in pits", self.vehicle_index)
133 }
134}
135
136/// Payload for the race winner event
137///
138/// The event announcing the race winner carries the vehicle index of the winner as its payload.
139///
140/// # Examples
141///
142/// ```
143/// # use f1_api::packet::event::{Event, RaceWinner};
144/// #
145/// # let race_winner = RaceWinner::new(0);
146/// # let event = Event::RaceWinner(race_winner);
147/// #
148/// // Simplified use in a match statement
149/// match event {
150/// Event::RaceWinner(winner) => {
151/// assert_eq!(0, winner.vehicle_index());
152/// }
153/// # _ => panic!("Example should never fail")
154/// }
155/// ```
156#[derive(
157 new, Debug, Getters, CopyGetters, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash, Default,
158)]
159pub struct RaceWinner {
160 /// Returns the index of the car that has won the race.
161 #[getset(get_copy = "pub")]
162 vehicle_index: VehicleIndex,
163}
164
165impl Display for RaceWinner {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 write!(f, "race winner in car #{}", self.vehicle_index)
168 }
169}
170
171/// Events that can occur during the course of a session
172///
173/// The F1 games send event packets whenever a certain event occurs in a session. Depending on the
174/// game, only a subset of the defined events may be published. Some events carry a payload that
175/// further describes the event. For example, the event declaring the race winner sends with it the
176/// vehicle index of said winner.
177#[derive(Debug, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash)]
178pub enum Event {
179 /// The chequered flag signals the end of the race.
180 ChequeredFlag,
181
182 /// DRS is disabled at the beginning of the race, and can be disabled throughout the race in
183 /// case of poor weather conditions or yellow flags in the DRS activation zone.
184 DrsDisabled,
185
186 /// DRS gets enabled after the first two laps of a race. In case DRS is disabled during a race,
187 /// e.g. due to poor weather conditions, it can be re-enabled once the conditions have cleared.
188 DrsEnabled,
189
190 /// When a driver achieves the fastest lap of the race, the event publishes the driver and their
191 /// time.
192 FastestLap(FastestLap),
193
194 /// At the end of the race, the race winner is announced in an event.
195 RaceWinner(RaceWinner),
196
197 /// Drivers can retire from a race, for example after their car suffers technical issues. The
198 /// retirement is announced as an event with the driver as the payload.
199 Retirement(Retirement),
200
201 /// The end of a session is announced in an event.
202 SessionEnded,
203
204 /// The start of a session is announced in an event.
205 SessionStarted,
206
207 /// When a teammate enters the pits, an event carrying their vehicle index is published.
208 TeammatesInPits(TeammateInPits),
209}
210
211impl Default for Event {
212 fn default() -> Self {
213 Event::SessionStarted
214 }
215}
216
217impl Display for Event {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 match self {
220 Event::SessionStarted => write!(f, "Session started"),
221 Event::SessionEnded => write!(f, "Session ended"),
222 Event::FastestLap(lap) => write!(
223 f,
224 "Fastest lap by car #{} ({}s)",
225 lap.vehicle_index,
226 lap.time.as_secs_f32()
227 ),
228 Event::Retirement(retirement) => write!(f, "Car #{} retired", retirement.vehicle_index),
229 Event::DrsEnabled => write!(f, "DRS enabled"),
230 Event::DrsDisabled => write!(f, "DRS disabled"),
231 Event::TeammatesInPits(teammate) => {
232 write!(f, "Teammate in car #{} in pits", teammate.vehicle_index)
233 }
234 Event::ChequeredFlag => write!(f, "Chequered flag"),
235 Event::RaceWinner(winner) => write!(f, "Car #{} won the race", winner.vehicle_index),
236 }
237 }
238}
239
240/// Packet containing details about an event that occurred in the session
241///
242/// The modern F1 games send event packets with details about events that occur in a session. The
243/// frequency with which these packets are sent is not fixed, but rather packets are sent whenever
244/// events occur.
245#[derive(new, Debug, Getters, PartialEq, Copy, Clone, Eq, Ord, PartialOrd, Hash)]
246pub struct EventPacket {
247 /// Returns the packet header prefixing the event packet.
248 #[getset(get = "pub")]
249 header: Header,
250
251 /// Returns the event from the event packet.
252 #[getset(get = "pub")]
253 event: Event,
254}
255
256impl Display for EventPacket {
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 write!(
259 f,
260 "EventPacket {{ header: {}, event: {} }}",
261 self.header, self.event
262 )
263 }
264}