Update API 2.5 weather module

- Fix types
- Heper methods
This commit is contained in:
Candifloss 2025-10-09 01:05:06 +05:30
parent 6959ec1e67
commit 352eea2a4a
2 changed files with 60 additions and 32 deletions

View File

@ -8,4 +8,4 @@ toml = "0.9.6"
dirs = "6.0.0" dirs = "6.0.0"
serde = { version = "1.0.225", features = ["derive"] } serde = { version = "1.0.225", features = ["derive"] }
serde_json = "1.0.145" serde_json = "1.0.145"
chrono = "0.4.42" chrono = { version = "0.4.42", features = ["serde"] }

View File

@ -1,14 +1,13 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Coord { pub struct Coord {
pub lon: f64, pub lon: f64,
pub lat: f64, pub lat: f64,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Weather { pub struct Weather {
pub id: u32, pub id: u32,
pub main: String, pub main: String,
@ -16,74 +15,81 @@ pub struct Weather {
pub icon: String, pub icon: String,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Main { pub struct Main {
pub temp: f32, pub temp: Option<f32>,
#[serde(default)]
pub feels_like: Option<f32>, pub feels_like: Option<f32>,
#[serde(default)]
pub temp_min: Option<f32>, pub temp_min: Option<f32>,
#[serde(default)]
pub temp_max: Option<f32>, pub temp_max: Option<f32>,
#[serde(default)]
pub pressure: Option<u32>, pub pressure: Option<u32>,
#[serde(default)]
pub humidity: Option<u8>, pub humidity: Option<u8>,
#[serde(default)]
pub sea_level: Option<u32>, pub sea_level: Option<u32>,
#[serde(default)]
pub grnd_level: Option<u32>, pub grnd_level: Option<u32>,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Wind { pub struct Wind {
pub speed: Option<f32>, pub speed: Option<f32>,
pub deg: Option<u16>, pub deg: Option<u16>,
pub gust: Option<f32>, pub gust: Option<f32>,
} }
#[derive(Debug, Deserialize, Serialize, Default)] #[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Clouds { pub struct Clouds {
pub all: Option<u8>, pub all: Option<u8>,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Precipitation { pub struct Precipitation {
#[serde(rename = "1h")] #[serde(rename = "1h", default)]
pub one_hour: Option<f32>, pub one_hour: Option<f32>,
#[serde(rename = "3h")] #[serde(rename = "3h", default)]
pub three_hour: Option<f32>, pub three_hour: Option<f32>,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Sys { pub struct Sys {
pub r#type: Option<u8>, pub r#type: Option<u8>,
pub id: Option<u32>, pub id: Option<u32>,
pub country: Option<String>, pub country: Option<String>,
pub sunrise: Option<u64>, #[serde(with = "chrono::serde::ts_seconds_option")]
pub sunset: Option<u64>, pub sunrise: Option<DateTime<Utc>>,
#[serde(with = "chrono::serde::ts_seconds_option")]
pub sunset: Option<DateTime<Utc>>,
pub message: Option<f64>,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct WeatherResponse { pub struct WeatherResponse {
pub cod: Option<u16>, // Http code
pub message: Option<String>, // Http error message
pub coord: Option<Coord>, pub coord: Option<Coord>,
#[serde(default)] #[serde(default)]
pub weather: Vec<Weather>, pub weather: Vec<Weather>,
pub base: Option<String>, pub base: Option<String>,
pub main: Main, pub main: Option<Main>,
pub visibility: Option<u32>, pub visibility: Option<u32>,
pub wind: Option<Wind>,
pub clouds: Option<Clouds>,
/// Optional precipitation data
/// "rain": { "1h": f32 } or "3h": f32
#[serde(default)]
pub rain: Option<Precipitation>,
/// "snow": { "1h": f32 } or "3h": f32
#[serde(default)]
pub snow: Option<Precipitation>,
#[serde(with = "chrono::serde::ts_seconds_option")] #[serde(with = "chrono::serde::ts_seconds_option")]
pub dt: Option<DateTime<Utc>>, pub dt: Option<DateTime<Utc>>,
pub sys: Sys, pub sys: Option<Sys>,
pub timezone: Option<i32>, pub timezone: Option<i32>,
pub id: Option<u64>, pub id: Option<u64>,
pub name: String, pub name: Option<String>,
pub cod: Option<u16>, #[serde(default)]
pub wind: Option<Wind>,
#[serde(default)]
pub clouds: Option<Clouds>,
#[serde(default)]
pub rain: Option<Precipitation>, // "rain": { "1h": f32 } or "3h": f32
#[serde(default)]
pub snow: Option<Precipitation>, // "snow": { "1h": f32 } or "3h": f32
} }
impl WeatherResponse { impl WeatherResponse {
@ -92,6 +98,28 @@ impl WeatherResponse {
} }
pub fn is_success(&self) -> bool { pub fn is_success(&self) -> bool {
self.cod.map_or(true, |code| code == 200) matches!(self.cod, Some(200))
}
pub fn temperature(&self) -> Option<f32> {
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}")
} }
} }