use serde_json::Value; use std::{fs, path::Path}; const CONFIG_PATH: &str = "/home/adam/.config/forecast"; #[derive(Debug)] struct WeatherInfo { icon: char, temp: i32, } fn main() { let data = request_weather(setup()); if data.is_err() { println!(" ??°C "); return; } let (a, b) = parse_weather(data.unwrap()); let trend = get_trend_icon(a.temp, b.temp); println!( " {} {}°C {} {} {}°C ", a.icon, a.temp, trend, b.icon, b.temp ); } fn setup() -> (String, String) { let city_id = read_file("city_id"); let api_key = read_file("api_key"); let weather_url: String = format!( "https://api.openweathermap.org/data/2.5/weather?id={}&appid={}&units=metric", city_id, api_key ); let forecast_url: String = format!( "https://api.openweathermap.org/data/2.5/forecast?id={}&appid={}&units=metric&cnt=1", city_id, api_key ); (weather_url, forecast_url) } fn read_file(file_name: &str) -> String { let path = Path::new(CONFIG_PATH).join(file_name); fs::read_to_string(path.to_string_lossy().to_string()).unwrap() } fn request_weather( (weather_url, forecast_url): (String, String), ) -> Result<(String, String), reqwest::Error> { let a = reqwest::blocking::get(weather_url)?.text()?; let b = reqwest::blocking::get(forecast_url)?.text()?; Ok((a, b)) } fn parse_weather((a, b): (String, String)) -> (WeatherInfo, WeatherInfo) { ( parse_current(serde_json::from_str(&a).unwrap()).unwrap(), parse_forecast(serde_json::from_str(&b).unwrap()).unwrap(), ) } fn parse_current(data: Value) -> Option { let i = data["weather"][0]["icon"].as_str()?; let t = data["main"]["temp"].as_f64()?.round(); Some(WeatherInfo { icon: get_weather_icon(i), temp: t as i32, }) } fn parse_forecast(data: Value) -> Option { let i = data["list"][0]["weather"][0]["icon"].as_str()?; let t = data["list"][0]["main"]["temp"].as_f64()?.round(); Some(WeatherInfo { icon: get_weather_icon(i), temp: t as i32, }) } fn get_weather_icon(code: &str) -> char { match code { "01d" => '', // Clear sky - day "01n" => '', // Clear sky - night "02d" => '', // Few clouds (11-25%) - day "02n" => '', // Few clouds (11-25%) - night "03d" | "03n" => '', // Scattered clouds (25-50%) - day/night "04d" | "04n" => '', // Broken / Overcast clouds (51-84% / 85-100%) - day/night "09d" => '', // Shower rain - day "09n" => '', // Shower rain - night "10d" => '', // Moderate / heavy rain - day "10n" => '', // Moderate / heavy rain - night "11d" => '', // Thunderstorm - day "11n" => '', // Thunderstorm - night "13d" => '', // Snow - day "13n" => '', // Snow - night "50d" => '', // Fog - day "50n" => '', // Fog - night _ => '', // ?? } } fn get_trend_icon(t1: i32, t2: i32) -> char { if t1 < t2 { '' } else if t1 > t2 { '' } else { '' } }