use std::collections::HashMap;
use crate::keys::OpenF1Key;
use crate::query::{QueryParams, QueryValue};
fn insert_optional(params: &mut QueryParams, key: &str, value: Option<QueryValue>) {
if let Some(value) = value {
params.insert(key.to_string(), value);
}
}
macro_rules! list_params {
($name:ident { $($field:ident : $ty:ty),* $(,)? }) => {
#[derive(Debug, Default, Clone)]
pub struct $name {
$(pub $field: Option<$ty>,)*
}
impl From<$name> for QueryParams {
fn from(value: $name) -> Self {
let mut params = QueryParams::new();
$(insert_optional(&mut params, stringify!($field), value.$field.map(Into::into));)*
params
}
}
};
}
list_params!(CarDataListParams {
driver_number: i64,
session_key: OpenF1Key,
speed: QueryFilter,
});
list_params!(ChampionshipDriversListParams {
session_key: OpenF1Key,
driver_number: i64,
});
list_params!(ChampionshipTeamsListParams {
session_key: OpenF1Key,
team_name: String,
});
list_params!(DriversListParams {
session_key: OpenF1Key,
driver_number: i64,
});
list_params!(IntervalsListParams {
session_key: OpenF1Key,
interval: QueryFilter,
});
list_params!(LapsListParams {
session_key: OpenF1Key,
driver_number: i64,
lap_number: QueryFilter,
});
list_params!(LocationListParams {
session_key: OpenF1Key,
driver_number: i64,
date: QueryFilter,
});
list_params!(MeetingsListParams {
year: i64,
country_name: String,
});
list_params!(OvertakesListParams {
session_key: OpenF1Key,
});
list_params!(PitListParams {
session_key: OpenF1Key,
});
list_params!(PositionListParams {
session_key: OpenF1Key,
driver_number: i64,
});
list_params!(RaceControlListParams {
session_key: OpenF1Key,
});
list_params!(SessionsListParams {
country_name: String,
session_name: String,
year: i64,
});
list_params!(SessionResultListParams {
session_key: OpenF1Key,
position: QueryFilter,
});
list_params!(StartingGridListParams {
session_key: OpenF1Key,
});
list_params!(StintsListParams {
session_key: OpenF1Key,
driver_number: i64,
});
list_params!(TeamRadioListParams {
session_key: OpenF1Key,
driver_number: i64,
});
list_params!(WeatherListParams {
session_key: OpenF1Key,
});
#[derive(Debug, Clone, Default)]
pub struct QueryFilter {
pub eq: Option<QueryValue>,
pub gt: Option<QueryValue>,
pub gte: Option<QueryValue>,
pub lt: Option<QueryValue>,
pub lte: Option<QueryValue>,
}
impl From<QueryFilter> for QueryValue {
fn from(value: QueryFilter) -> Self {
let mut filter = HashMap::new();
if let Some(value) = value.eq {
filter.insert("eq".to_string(), value);
}
if let Some(value) = value.gt {
filter.insert("gt".to_string(), value);
}
if let Some(value) = value.gte {
filter.insert("gte".to_string(), value);
}
if let Some(value) = value.lt {
filter.insert("lt".to_string(), value);
}
if let Some(value) = value.lte {
filter.insert("lte".to_string(), value);
}
QueryValue::Filter(filter)
}
}
impl From<i64> for QueryValue {
fn from(value: i64) -> Self {
QueryValue::Number(value)
}
}
impl From<i32> for QueryValue {
fn from(value: i32) -> Self {
QueryValue::Number(i64::from(value))
}
}
impl From<f64> for QueryValue {
fn from(value: f64) -> Self {
QueryValue::Float(value)
}
}
impl From<String> for QueryValue {
fn from(value: String) -> Self {
QueryValue::Scalar(value)
}
}
impl From<&str> for QueryValue {
fn from(value: &str) -> Self {
QueryValue::Scalar(value.to_string())
}
}