1use std::fmt::Display;
2use serde::{Serialize, Deserialize};
3use chrono::{DateTime, TimeZone, Utc};
4
5use super::{Current, Location, Alerts, AirQuality, Condition, Date, Time};
6
7
8pub struct Temperature(f32, f32);
9
10impl Temperature {
11 pub fn min(&self) -> f32 { self.0 }
12 pub fn max(&self) -> f32 { self.1 }
13}
14
15impl Display for Temperature {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 write!(f, "min: {}\n max: {}", self.min(), self.max())
18 }
19}
20
21
22#[derive(Debug, Serialize, Deserialize, PartialEq)]
23pub struct Day {
24 maxtemp_c: f32,
25 maxtemp_f: f32,
26 mintemp_c: f32,
27 mintemp_f: f32,
28 pub avgtemp_c: f32,
29 pub avgtemp_f: f32,
30 pub maxwind_mph: f32,
31 pub maxwind_kph: f32,
32 pub totalprecip_mm: f32,
33 pub totalprecip_in: f32,
34 pub avgvis_km: f32,
35 pub avgvis_miles: f32,
36 pub avghumidity: f32,
37 pub condition: Condition,
38 pub uv: f32
39}
40
41impl Day {
42 pub fn temp_c(&self) -> Temperature {
43 Temperature(self.mintemp_c, self.maxtemp_c)
44 }
45
46 pub fn temp_f(&self) -> Temperature {
47 Temperature(self.mintemp_f, self.maxtemp_f)
48 }
49}
50
51
52#[derive(Debug, Serialize, Deserialize, PartialEq)]
53pub enum MoonPhase {
54 #[serde(rename = "New Moon")]
55 NewMoon,
56 #[serde(rename = "Waxing Crescent")]
57 WaxingCrescent,
58 #[serde(rename = "First Quarter")]
59 FirstQuarter,
60 #[serde(rename = "Waxing Gibbous")]
61 WaxingGibbous,
62 #[serde(rename = "Full Moon")]
63 FullMoon,
64 #[serde(rename = "Waning Gibbous")]
65 WaningGibbous,
66 #[serde(rename = "Last Quarter")]
67 LastQuarter,
68 #[serde(rename = "Waning Crescent")]
69 WaningCrescent,
70 #[serde(rename = "Third Quarter")]
71 ThirdQuarter
72}
73
74impl Display for MoonPhase {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 MoonPhase::NewMoon => write!(f, "New Moon"),
78 MoonPhase::WaxingCrescent => write!(f, "Waxing Crescent"),
79 MoonPhase::FirstQuarter => write!(f, "First Quarter"),
80 MoonPhase::WaxingGibbous => write!(f, "Waxing Gibbous"),
81 MoonPhase::FullMoon => write!(f, "Full Moon"),
82 MoonPhase::WaningCrescent => write!(f, "Waning Crescent"),
83 MoonPhase::LastQuarter => write!(f, "Last Quarter"),
84 MoonPhase::WaningGibbous => write!(f, "Waning Gibbous"),
85 MoonPhase::ThirdQuarter => write!(f, "Third Quarter")
86 }
87 }
88}
89
90
91#[derive(Debug, Serialize, Deserialize, PartialEq)]
92pub struct Astro {
93 pub sunrise: String,
94 pub sunset: String,
95 pub moonrise: String,
96 pub moonset: String,
97 pub moon_phase: MoonPhase,
98 pub moon_illumination: String
99}
100
101impl Astro {
102 pub fn sunrise(&self) -> DateTime<Utc> {
103 Utc.datetime_from_str(&self.sunrise, fmt:"%m:%d %p").unwrap()
104 }
105
106 pub fn sunset(&self) -> DateTime<Utc> {
107 Utc.datetime_from_str(&self.sunset, fmt:"%m:%d %p").unwrap()
108 }
109
110 pub fn moonrise(&self) -> DateTime<Utc> {
111 Utc.datetime_from_str(&self.moonrise, fmt:"%m:%d %p").unwrap()
112 }
113
114 pub fn moonset(&self) -> DateTime<Utc> {
115 Utc.datetime_from_str(&self.moonset, fmt:"%m:%d %p").unwrap()
116 }
117}
118
119
120#[derive(Debug, Serialize, Deserialize, PartialEq)]
121pub struct Hour {
122 pub time_epoch: i64,
123 pub time: String,
124 pub temp_c: f32,
125 pub temp_f: f32,
126 pub condition: Condition,
127 pub wind_mph: f32,
128 pub wind_kph: f32,
129 pub wind_degree: u32,
130 pub wind_dir: String,
131 pub pressure_mb: f32,
132 pub pressure_in: f32,
133 pub precip_mm: f32,
134 pub precip_in: f32,
135 pub humidity: u32,
136 pub cloud: u32,
137 pub feelslike_c: f32,
138 pub feelslike_f: f32,
139 pub windchill_c: f32,
140 pub windchill_f: f32,
141 pub heatindex_c: f32,
142 pub heatindex_f: f32,
143 pub dewpoint_c: f32,
144 pub dewpoint_f: f32,
145 pub will_it_rain: u8,
146 pub will_it_snow: u8,
147 pub is_day: u8,
148 pub vis_km: f32,
149 pub vis_miles: f32,
150 pub chance_of_rain: u32,
151 pub chance_of_snow: u32,
152 pub gust_mph: f32,
153 pub gust_kph: f32,
154 pub air_quality: Option<AirQuality>
155}
156
157impl Hour {
158 pub fn will_it_rain(&self) -> bool {
159 self.will_it_rain == 1
160 }
161
162 pub fn will_it_snow(&self) -> bool {
163 self.will_it_snow == 1
164 }
165
166 pub fn is_day(&self) -> bool {
167 self.is_day == 1
168 }
169}
170
171impl Time for Hour {
172 fn time(&self) -> DateTime<Utc> {
173 self._time_from_str(&self.time).unwrap()
174 }
175
176 fn time_epoch(&self) -> DateTime<Utc> {
177 Utc.timestamp(self.time_epoch, nsecs:0)
178 }
179}
180
181
182#[derive(Debug, Serialize, Deserialize, PartialEq)]
183pub struct ForecastDay {
184 pub date: String,
185 pub date_epoch: i64,
186 pub day: Day,
187 pub astro: Astro,
188 pub hour: Vec<Hour>
189}
190
191impl Date for ForecastDay {
192 fn date(&self) -> DateTime<Utc> {
193 self._date_from_str(&self.date).unwrap()
194 }
195
196 fn date_epoch(&self) -> DateTime<Utc> {
197 Utc.timestamp(self.date_epoch, nsecs:0)
198 }
199}
200
201
202#[derive(Debug, Serialize, Deserialize, PartialEq)]
203pub struct _Forecast {
204 #[serde(rename = "forecastday")]
205 pub forecast_day: Vec<ForecastDay>
206}
207
208
209#[derive(Debug, Serialize, Deserialize, PartialEq)]
210pub struct Forecast {
211 pub location: Location,
212 pub current: Current,
213 pub forecast: _Forecast,
214 pub alerts: Option<Alerts>
215}
216