use crate::{Frequency, LatLon, Meteostat, MeteostatError, MonthlyLazyFrame, RequiredData};
use bon::bon;
pub struct MonthlyClient<'a> {
client: &'a Meteostat,
}
#[bon]
impl<'a> MonthlyClient<'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<MonthlyLazyFrame, MeteostatError> {
let frame = self
.client
.data_from_station()
.station(station)
.maybe_required_data(required_data)
.frequency(Frequency::Monthly)
.call()
.await?;
Ok(MonthlyLazyFrame::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<MonthlyLazyFrame, 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::Monthly)
.call()
.await?;
Ok(MonthlyLazyFrame::new(frame))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{RequiredData, Year};
fn berlin_location() -> LatLon {
LatLon(52.520008, 13.404954)
}
#[tokio::test]
async fn test_monthly_from_station() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.monthly()
.station("06240") .call()
.await?
.frame
.collect()?;
assert!(data.height() > 0, "Expected some monthly data");
Ok(())
}
#[tokio::test]
async fn test_monthly_from_station_with_filter() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.monthly()
.station("10382") .required_data(RequiredData::FullYear(2023))
.call()
.await?
.get_for_period(Year(2023))?
.frame
.collect()?;
assert!(
data.height() > 0,
"Expected > 0 rows of monthly data for 2023 after inventory filter"
);
Ok(())
}
#[tokio::test]
async fn test_monthly_from_location() -> Result<(), MeteostatError> {
let client = Meteostat::new().await?;
let data = client
.monthly()
.location(berlin_location())
.call() .await?
.frame
.collect()?;
assert!(
data.height() > 0,
"Expected some monthly data for Berlin area"
);
Ok(())
}
}