| 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 | |