1 | use std::fmt::Display; |
2 | use serde::{Serialize, Deserialize}; |
3 | use chrono::{DateTime, TimeZone, Utc}; |
4 | |
5 | use super::{Current, Location, Alerts, AirQuality, Condition, Date, Time}; |
6 | |
7 | |
8 | pub struct Temperature(f32, f32); |
9 | |
10 | impl Temperature { |
11 | pub fn min(&self) -> f32 { self.0 } |
12 | pub fn max(&self) -> f32 { self.1 } |
13 | } |
14 | |
15 | impl 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)] |
23 | pub 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 | |
41 | impl 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)] |
53 | pub 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 | |
74 | impl 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)] |
92 | pub 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 | |
101 | impl 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)] |
121 | pub 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 | |
157 | impl 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 | |
171 | impl 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)] |
183 | pub 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 | |
191 | impl 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)] |
203 | pub struct _Forecast { |
204 | #[serde(rename = "forecastday" )] |
205 | pub forecast_day: Vec<ForecastDay> |
206 | } |
207 | |
208 | |
209 | #[derive (Debug, Serialize, Deserialize, PartialEq)] |
210 | pub struct Forecast { |
211 | pub location: Location, |
212 | pub current: Current, |
213 | pub forecast: _Forecast, |
214 | pub alerts: Option<Alerts> |
215 | } |
216 | |