use crate::{DailyLazyFrame, Frequency, LatLon, Meteostat, MeteostatError, RequiredData};
use bon::bon;
pub struct DailyClient<'a> {
client: &'a Meteostat,
}
#[bon] impl<'a> DailyClient<'a> {
pub(crate) const fn new(client: &'a Meteostat) -> Self {
Self { client }
}
#[builder(start_fn = station)]
#[doc(hidden)]
pub async fn build_station(
&self,
#[builder(start_fn)] station: &str,
required_data: Option<RequiredData>,
) -> Result<DailyLazyFrame, MeteostatError> {
let frame = self
.client
.data_from_station()
.station(station)
.maybe_required_data(required_data)
.frequency(Frequency::Daily)
.call()
.await?;
Ok(DailyLazyFrame::new(frame))
}
#[builder(start_fn = location)] #[doc(hidden)] pub async fn build_location(
&self,
#[builder(start_fn)] coordinate: LatLon, max_distance_km: Option<f64>, station_limit: Option<usize>, required_data: Option<RequiredData>, ) -> Result<DailyLazyFrame, MeteostatError> {
let frame = self
.client
.data_from_location()
.location(coordinate) .maybe_max_distance_km(max_distance_km) .maybe_station_limit(station_limit) .maybe_required_data(required_data) .frequency(Frequency::Daily) .call() .await?;
Ok(DailyLazyFrame::new(frame))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Year;
use chrono::NaiveDate;
fn berlin_location() -> LatLon {
LatLon(52.520008, 13.404954)
}
#[tokio::test]
async fn test_daily_from_station_for_period() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.daily()
.station("06240") .call()
.await?
.get_for_period(Year(2023))?
.frame
.collect()?;
assert!(data.height() > 0, "Expected some daily data for 2023");
Ok(())
}
#[tokio::test]
async fn test_daily_from_station_with_filter() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.daily()
.station("06240") .required_data(RequiredData::FullYear(2023))
.call()
.await?
.get_for_period(Year(2023))? .frame
.collect()?;
assert!(
data.height() > 300,
"Expected >300 days of data for 2023 after inventory filter"
);
Ok(())
}
#[tokio::test]
async fn test_daily_from_station_at_specific_date() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.daily()
.station("06240") .call()
.await?
.get_at(NaiveDate::from_ymd_opt(2023, 7, 15).unwrap())? .frame
.collect()?;
assert!(data.height() <= 1, "Expected 0 or 1 row for specific day");
Ok(())
}
#[tokio::test]
async fn test_daily_from_location_for_period() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.daily()
.location(berlin_location())
.call() .await?
.get_for_period(Year(2023))?
.frame
.collect()?;
assert!(
data.height() > 0,
"Expected some daily data for Berlin area in 2023"
);
Ok(())
}
}