use reqwest::{Client, Response, Url}; use serde::Deserialize; use std::error::Error; use crate::Context; const LATITUDE: &'static str = "51.43"; const LONGITUDE: &'static str = "5.47"; #[derive(Debug, Deserialize)] struct Current { weather: Vec, main: Main, } #[derive(Debug, Deserialize)] struct Weather { description: String, } #[derive(Debug, Deserialize)] struct Main { temp: f32, feels_like: f32, } #[derive(Debug, Deserialize)] struct OneCall { daily: Vec, } #[derive(Debug, Deserialize)] struct Daily { temp: Temp, weather: Vec, pop: f32, } #[derive(Debug, Deserialize)] struct Temp { day: f32, } async fn request(context: &Context, url: &str) -> reqwest::Result { let client = Client::new(); let mut url = Url::parse(url).unwrap(); url.query_pairs_mut() .append_pair("appid", &context.openweather_api_key) .append_pair("lat", LATITUDE) .append_pair("lon", LONGITUDE) .append_pair("units", "metric") .append_pair("lang", "nl"); client.get(url).send().await } pub async fn get_weather(context: &Context) -> Result> { let url = "https://api.openweathermap.org/data/2.5/weather"; let resp = request(&context, &url).await?; let cur_weather: Current = resp.json().await?; let description = cur_weather.weather.first().unwrap().description.clone(); let temperature = cur_weather.main.temp.round() as u32; let temperature_feel = cur_weather.main.feels_like.round() as u32; let weather = format!( "Het weer in Eindhoven is op het moment {description} en het is {temperature} graden \ buiten en dat voelt als {temperature_feel} graden", description = description, temperature = temperature, temperature_feel = temperature_feel, ); Ok(weather) } pub async fn get_forecast(context: &Context) -> Result> { let url = "https://api.openweathermap.org/data/2.5/onecall"; let resp = request(&context, &url).await?; let weather_forecast: OneCall = resp.json().await?; let today = weather_forecast.daily.first().unwrap(); let description = today.weather.first().unwrap().description.clone(); let temperature_day = today.temp.day.round() as u32; let rain_pct = (today.pop * 100.0).round() as u8; let forecast = format!( "De weersverwachting van vandaag voor Eindhoven is {description} met een \ middagtemperatuur van {temperature_day} graden en {rain_pct} procent kans op regen", description = description, temperature_day = temperature_day, rain_pct = rain_pct, ); Ok(forecast) }