From 352eea2a4a9bd615720cbcf22f22fac57ee0828a Mon Sep 17 00:00:00 2001 From: Candifloss Date: Thu, 9 Oct 2025 01:05:06 +0530 Subject: [PATCH] Update API 2.5 weather module - Fix types - Heper methods --- owm_api25/Cargo.toml | 2 +- owm_api25/src/weather.rs | 90 ++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/owm_api25/Cargo.toml b/owm_api25/Cargo.toml index 8bb02cf..f6ce458 100644 --- a/owm_api25/Cargo.toml +++ b/owm_api25/Cargo.toml @@ -8,4 +8,4 @@ toml = "0.9.6" dirs = "6.0.0" serde = { version = "1.0.225", features = ["derive"] } serde_json = "1.0.145" -chrono = "0.4.42" +chrono = { version = "0.4.42", features = ["serde"] } diff --git a/owm_api25/src/weather.rs b/owm_api25/src/weather.rs index 2ea2fa8..d99ec95 100644 --- a/owm_api25/src/weather.rs +++ b/owm_api25/src/weather.rs @@ -1,14 +1,13 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct Coord { pub lon: f64, pub lat: f64, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct Weather { pub id: u32, pub main: String, @@ -16,74 +15,81 @@ pub struct Weather { pub icon: String, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct Main { - pub temp: f32, + pub temp: Option, + #[serde(default)] pub feels_like: Option, + #[serde(default)] pub temp_min: Option, + #[serde(default)] pub temp_max: Option, + #[serde(default)] pub pressure: Option, + #[serde(default)] pub humidity: Option, + #[serde(default)] pub sea_level: Option, + #[serde(default)] pub grnd_level: Option, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Wind { pub speed: Option, pub deg: Option, pub gust: Option, } -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Clouds { pub all: Option, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Precipitation { - #[serde(rename = "1h")] + #[serde(rename = "1h", default)] pub one_hour: Option, - #[serde(rename = "3h")] + #[serde(rename = "3h", default)] pub three_hour: Option, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct Sys { pub r#type: Option, pub id: Option, pub country: Option, - pub sunrise: Option, - pub sunset: Option, + #[serde(with = "chrono::serde::ts_seconds_option")] + pub sunrise: Option>, + #[serde(with = "chrono::serde::ts_seconds_option")] + pub sunset: Option>, + pub message: Option, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct WeatherResponse { + pub cod: Option, // Http code + pub message: Option, // Http error message pub coord: Option, #[serde(default)] pub weather: Vec, pub base: Option, - pub main: Main, + pub main: Option
, 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 sys: Option, pub timezone: Option, pub id: Option, - pub name: String, - pub cod: Option, + pub name: Option, + #[serde(default)] + pub wind: Option, + #[serde(default)] + pub clouds: Option, + #[serde(default)] + pub rain: Option, // "rain": { "1h": f32 } or "3h": f32 + #[serde(default)] + pub snow: Option, // "snow": { "1h": f32 } or "3h": f32 } impl WeatherResponse { @@ -92,6 +98,28 @@ impl WeatherResponse { } pub fn is_success(&self) -> bool { - self.cod.map_or(true, |code| code == 200) + matches!(self.cod, Some(200)) + } + + pub fn temperature(&self) -> Option { + self.main.as_ref().map(|m| m.temp)? + } + + pub fn city(&self) -> Option<&str> { + self.name.as_deref() + } + + pub fn country(&self) -> Option<&str> { + self.sys.as_ref()?.country.as_deref() + } + + pub fn summary(&self) -> String { + let temp = self + .temperature() + .map_or("-".into(), |t| format!("{t:.1}°")); + let desc = self + .primary_weather() + .map_or("N/A", |w| w.description.as_str()); + format!("{desc}, {temp}") } }