use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Deserialize, Serialize)] pub struct Coord { pub lon: f64, pub lat: f64, } #[derive(Debug, Deserialize, Serialize)] pub struct Weather { pub id: u32, pub main: String, pub description: String, pub icon: String, } #[derive(Debug, Deserialize, Serialize)] pub struct Main { pub temp: f32, pub feels_like: Option, pub temp_min: Option, pub temp_max: Option, pub pressure: Option, pub humidity: Option, pub sea_level: Option, pub grnd_level: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct Wind { pub speed: Option, pub deg: Option, pub gust: Option, } #[derive(Debug, Deserialize, Serialize, Default)] pub struct Clouds { pub all: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct Precipitation { #[serde(rename = "1h")] pub one_hour: Option, #[serde(rename = "3h")] pub three_hour: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct Sys { pub r#type: Option, pub id: Option, pub country: Option, pub sunrise: Option, pub sunset: Option, } #[derive(Debug, Deserialize, Serialize)] pub struct WeatherResponse { pub coord: Option, #[serde(default)] pub weather: Vec, pub base: Option, pub main: Main, pub visibility: Option, pub wind: Option, pub clouds: Option, /// Optional precipitation data /// "rain": { "1h": f32 } or "3h": f32 #[serde(default)] pub rain: Option, /// "snow": { "1h": f32 } or "3h": f32 #[serde(default)] pub snow: Option, #[serde(with = "chrono::serde::ts_seconds_option")] pub dt: Option>, pub sys: Sys, pub timezone: Option, pub id: Option, pub name: String, pub cod: Option, } impl WeatherResponse { pub fn primary_weather(&self) -> Option<&Weather> { self.weather.first() } pub fn is_success(&self) -> bool { self.cod.map_or(true, |code| code == 200) } }