use std::fmt::Display;
use chrono::{DateTime, TimeZone, Timelike};
use super::BaseApi;
use crate::{Client, Query, Language, Forecast};
pub struct ForecastApi<'a, Tz: TimeZone>
where
Tz::Offset: Display
{
client: &'a Client,
query: Option<Query>,
days: Option<u8>,
dt: Option<DateTime<Tz>>,
hour: bool,
alerts: bool,
aqi: bool,
lang: Option<Language>
}
impl<'a, Tz: TimeZone> ForecastApi<'a, Tz>
where
Tz::Offset: Display,
{
pub fn new(client: &'a Client) -> Self {
Self {
client,
query: None,
days: None,
dt: None,
hour: false,
alerts: false,
aqi: false,
lang: None
}
}
pub fn query(mut self, query: Query) -> Self {
self.query = Some(query);
self
}
pub fn days(mut self, days: u8) -> Self {
self.days = Some(days);
self
}
pub fn dt(mut self, dt: DateTime<Tz>) -> Self {
self.dt = Some(dt);
self
}
pub fn hour(mut self) -> Self {
self.hour = true;
self
}
pub fn alerts(mut self) -> Self {
self.alerts = true;
self
}
pub fn aqi(mut self) -> Self {
self.aqi = true;
self
}
pub fn lang(mut self, lang: Language) -> Self {
self.lang = Some(lang);
self
}
}
impl<'a, Tz: TimeZone> BaseApi<'a> for ForecastApi<'a, Tz>
where
Tz::Offset: Display,
{
type Model = Forecast;
fn path(&self) -> &str {
"forecast"
}
fn client(&self) -> &'a Client {
self.client
}
fn params(&self) -> Vec<(&str, String)> {
let query = self.query.as_ref().unwrap();
let dt = self.dt.as_ref().unwrap();
let mut params = vec![
("key", self.client.api_key.clone()), ("q", query.to_string()), ("dt", format!("{}", dt.format("%Y-%m-%d"))),
("alerts", if self.alerts { "yes".to_string() } else { "no".to_string() }),
("aqi", if self.aqi { "yes".to_string() } else { "no".to_string() })
];
if let Some(days) = self.days {
params.push(("days", days.to_string()))
}
if self.hour {
params.push(("hour", dt.hour().to_string()))
}
if let Some(lang) = &self.lang {
params.push(("lang", lang.to_string()))
}
params
}
}