1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87use anyhow::Context;
use chrono::{Datelike, TimeZone, Weekday};
use chrono_tz::Tz;
use pirate_weather::apis::weather_api::{WeatherApi, WeatherApiClient};
use serde::Serialize;
use crate::config::Location;
#[derive(Serialize)]
pub(crate) struct TemplateForecast {
pub(crate) days: Vec<TemplateDay>,
pub(crate) location: Location,
}
#[derive(Serialize)]
pub(crate) struct TemplateDay {
pub(crate) time_formatted: String,
pub(crate) time_is_weekend: bool,
pub(crate) icon: String,
pub(crate) summary: String,
pub(crate) apparent_temperature_low: f64,
pub(crate) apparent_temperature_high: f64,
pub(crate) temperature_low: f64,
pub(crate) temperature_high: f64,
pub(crate) precip_probability: f64,
pub(crate) wind_speed: f64,
}
pub(crate) async fn get_forecast(
client: &WeatherApiClient,
key: &str,
location: &Location,
) -> anyhow::Result<TemplateForecast> {
let weather = client
.weather(
key,
&format!("{},{}", location.latitude, location.longitude),
Some("currently,minutely,alerts,hourly"),
None,
None,
None,
None,
None,
None,
)
.await?;
let mut days = vec![];
let tz: Tz = weather.timezone.unwrap().parse().unwrap();
let daily = weather
.daily
.with_context(|| "No daily object in response")?;
let data = daily.data.with_context(|| "No daily data in response")?;
for day in data {
let time = day
.time
.map(|timestamp| tz.timestamp_opt(timestamp as i64, 0))
.with_context(|| "No day time")?;
let time = time
.single()
.with_context(|| "Time zone conversion failed")?;
days.push(TemplateDay {
time_formatted: time.format("%a %b %d").to_string(),
time_is_weekend: time.weekday() == Weekday::Sat || time.weekday() == Weekday::Sun,
icon: day.icon.unwrap(),
summary: day.summary.unwrap(),
apparent_temperature_low: day.apparent_temperature_low.unwrap(),
apparent_temperature_high: day.apparent_temperature_high.unwrap(),
temperature_low: day.temperature_low.unwrap(),
temperature_high: day.temperature_high.unwrap(),
precip_probability: day.precip_probability.unwrap(),
wind_speed: day.wind_speed.unwrap(),
})
}
Ok(TemplateForecast {
days,
location: location.clone(),
})
}