ergast-rs 0.3.2

An async client for getting Formula 1 schedules, qualifying, and race results powered by the Ergast API
Documentation
use serde::Deserialize;
use serde_aux::field_attributes::deserialize_number_from_string;

use super::race_table::RaceTable;

#[derive(Deserialize)]
pub struct Response {
    #[serde(rename = "MRData")]
    pub data: MRData,
}

#[derive(Deserialize)]
pub struct MRData {
    pub xmlns: String,
    pub series: String,
    pub url: String,
    #[serde(deserialize_with = "deserialize_number_from_string")]
    pub limit: u32,
    #[serde(deserialize_with = "deserialize_number_from_string")]
    pub offset: u32,
    #[serde(deserialize_with = "deserialize_number_from_string")]
    pub total: u32,
    #[serde(rename = "RaceTable")]
    pub race_table: Option<RaceTable>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_deserialize_race_schedule() {
        let json = include_str!("../fixtures/api.f1.current.json");
        let resp: Response = serde_json::from_str(json).expect("failed to deserialize");
        let race_table = resp
            .data
            .race_table
            .expect("didn't find a race table in respose");

        // verify a data point to be safe, but we really care that we deserialize without panic
        let first_race = race_table
            .races
            .first()
            .expect("malformed fixture file didn't include first race");
        assert_eq!(first_race.name, "Bahrain Grand Prix");
    }

    #[test]
    fn test_deserialize_race_results() {
        let json = include_str!("../fixtures/api.f1.2020.16.results.json");
        let resp: Response = serde_json::from_str(json).expect("failed to deserialize");
        let race_table = resp
            .data
            .race_table
            .expect("didn't find a race table in respose");

        // verify a data point to be safe, but we really care that we deserialize without panic
        let first_race = race_table
            .races
            .first()
            .expect("malformed fixture file didn't include first race");
        let winner = &first_race
            .race_results
            .as_ref()
            .expect("malformed fixture file didn't include race results")
            .first()
            .expect("malformed fixture file didn't include first race result")
            .driver
            .code;
        // Checo won!
        assert_eq!(winner, "PER");
    }

    #[test]
    fn test_deserialize_sprint_results() {
        let json = include_str!("../fixtures/api.f1.2021.10.sprint.json");
        let resp: Response = serde_json::from_str(json).expect("failed to deserialize");
        let race_table = resp
            .data
            .race_table
            .expect("didn't find a race table in respose");

        // verify a data point to be safe, but we really care that we deserialize without panic
        let first_race = race_table
            .races
            .first()
            .expect("malformed fixture file didn't include first race");
        let winner = &first_race
            .sprint_results
            .as_ref()
            .expect("malformed fixture file didn't include race results")
            .first()
            .expect("malformed fixture file didn't include first race result")
            .driver
            .family_name;
        // Verstappen was on pole
        assert_eq!(winner, "Verstappen");
    }

    #[test]
    fn test_deserialize_qualifying_results() {
        let json = include_str!("../fixtures/api.f1.2022.2.qualifying.json");
        let resp: Response = serde_json::from_str(json).expect("failed to deserialize");
        let race_table = resp
            .data
            .race_table
            .expect("didn't find a race table in respose");

        // verify a data point to be safe, but we really care that we deserialize without panic
        let first_race = race_table
            .races
            .first()
            .expect("malformed fixture file didn't include first race");
        let winner = &first_race
            .qualifying_results
            .as_ref()
            .expect("malformed fixture file didn't include race results")
            .first()
            .expect("malformed fixture file didn't include first race result")
            .driver
            .family_name;
        // Checo was on Pole!
        assert_eq!(winner, "Pérez");
    }
}