From 4b2c8ae92ea42ce2680af5658fa3311b50d6581c Mon Sep 17 00:00:00 2001 From: Adam <56338480+adastx@users.noreply.github.com> Date: Sun, 24 Jul 2022 18:56:01 +0200 Subject: Clearer flow + error handling --- src/main.rs | 101 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/src/main.rs b/src/main.rs index cf4dc66..02622f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,5 @@ use serde_json::Value; -use std::error::Error; -use std::fs; -use std::path::Path; +use std::{fs, path::Path}; const CONFIG_PATH: &str = "/home/adam/.config/forecast"; @@ -12,70 +10,55 @@ struct WeatherInfo { } fn main() { - let (current_endpoint, forecast_endpoint) = init(); - let current_data = req_weather(current_endpoint).unwrap(); - let forecast_data = req_weather(forecast_endpoint).unwrap(); + let data = request_weather(setup()); + if data.is_err() { + println!(" ??°C "); + return; + } - let current_weather = parse_current(current_data).unwrap(); - let forecast_weather = parse_forecast(forecast_data).unwrap(); - let trend = get_trend(current_weather.temp, forecast_weather.temp); + let (a, b) = parse_weather(data.unwrap()); + let trend = get_trend_icon(a.temp, b.temp); println!( " {} {}°C {} {} {}°C ", - current_weather.icon, - current_weather.temp, - trend, - forecast_weather.icon, - forecast_weather.temp + a.icon, a.temp, trend, b.icon, b.temp ); } -fn init() -> (String, String) { - let city_id = read_config_file("city_id"); - let api_key = read_config_file("api_key"); - - let current_endpoint: String = format!( - "https://api.openweathermap.org/data/2.5/weather?id={}&appid={}&units=metric", - city_id, api_key - ); - let forecast_endpoint: String = format!( - "https://api.openweathermap.org/data/2.5/forecast?id={}&appid={}&units=metric&cnt=1", - city_id, api_key - ); - (current_endpoint, forecast_endpoint) -} - -fn read_config_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 req_weather(endpoint: String) -> Result> { - let resp = reqwest::blocking::get(endpoint)?.text()?; - Ok(serde_json::from_str(&resp)?) +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(response: Value) -> Option { - let icon_code = response["weather"][0]["icon"].as_str()?; - let temperature = response["main"]["temp"].as_f64()?.round(); - +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_icon(icon_code), - temp: temperature as i32, + icon: get_weather_icon(i), + temp: t as i32, }) } -fn parse_forecast(response: Value) -> Option { - let icon_code = response["list"][0]["weather"][0]["icon"].as_str()?; - let temperature = response["list"][0]["main"]["temp"].as_f64()?.round(); - +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_icon(icon_code), - temp: temperature as i32, + icon: get_weather_icon(i), + temp: t as i32, }) } -fn get_icon(code: &str) -> char { +fn get_weather_icon(code: &str) -> char { match code { "01d" => '', // Clear sky - day "01n" => '', // Clear sky - night @@ -97,7 +80,7 @@ fn get_icon(code: &str) -> char { } } -fn get_trend(t1: i32, t2: i32) -> char { +fn get_trend_icon(t1: i32, t2: i32) -> char { if t1 < t2 { '' } else if t1 > t2 { @@ -106,3 +89,23 @@ fn get_trend(t1: i32, t2: i32) -> char { '' } } + +fn setup() -> (String, String) { + let city_id = read_file("city_id"); + let api_key = read_file("api_key"); + + let current_endpoint: String = format!( + "https://api.openweathermap.org/data/2.5/weather?id={}&appid={}&units=metric", + city_id, api_key + ); + let forecast_endpoint: String = format!( + "https://api.openweathermap.org/data/2.5/forecast?id={}&appid={}&units=metric&cnt=1", + city_id, api_key + ); + (current_endpoint, forecast_endpoint) +} + +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() +} -- cgit v1.2.3-70-g09d2