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}