diff --git a/src/cli.rs b/src/cli.rs index dc402c0..90089e0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,28 +1,34 @@ use structopt::StructOpt; #[derive(Debug, StructOpt)] -#[structopt(name = "Open Meteo CLI", about = "CLI to extract data from Open Meteo")] -pub enum Options { - #[structopt(about = "Get current weather from a coordinate")] +#[structopt( + name = "Open Meteo CLI", + about = "CLI to extract meteorology data from Open Meteo" +)] +pub enum Arguments { + #[structopt(about = "Gets the current weather for a coordinate")] CurrentWeather { #[structopt(short = "l", long, help = "Latitude as a decimal number")] latitude: f32, - #[structopt(short = "g", long, help = "Altitude as a decimal number")] + #[structopt(short = "L", long, help = "Altitude as a decimal number")] longitude: f32, - #[structopt(short = "d", long, help = "Extracts if its day or night")] + #[structopt(short = "a", long, help = "Prints all the parameters")] + all: bool, + #[structopt(short = "d", long, help = "Prints if its day or night")] is_day: bool, - #[structopt(short = "t", long, help = "Extracts decimal temperature")] + #[structopt(short = "t", long, help = "Prints decimal temperature")] temperature: bool, - #[structopt(short = "s", long, help = "Extracts decimal wind speed")] + #[structopt(short = "w", long, help = "Prints decimal wind speed")] windspeed: bool, - #[structopt(short = "w", long, help = "Extracts angle direction")] + #[structopt(short = "W", long, help = "Prints wind direction angle")] winddirection: bool, #[structopt( short = "c", long, - help = "Clean the output, and only show the values separates by commas. - The order is: is_day, temperature, windspeed, winddirection" + help = "Cleans the output, and only shows the values separates by commas. +- ORDER: is_day, temperature, windspeed, winddirection +- EXAMPLE: 1,22.4,12.5,170.0" )] clean: bool, }, diff --git a/src/current_weater.rs b/src/current_weater.rs new file mode 100644 index 0000000..7178f8c --- /dev/null +++ b/src/current_weater.rs @@ -0,0 +1,22 @@ +pub struct CurrentWeather { + current_weather: serde_json::Value, + clean: bool, +} + +impl CurrentWeather { + pub fn new(current_weather: serde_json::Value, clean: bool) -> CurrentWeather { + CurrentWeather { + current_weather, + clean, + } + } + + pub fn extract_data(&self, data_name: &str, data_description: &str) -> String { + let data = &self.current_weather[data_name]; + if self.clean { + format!("{data}") + } else { + format!("{data_description}: {data}") + } + } +} diff --git a/src/main.rs b/src/main.rs index 089c751..02ee787 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,68 @@ mod cli; +mod current_weater; -use cli::Options; +use std::process::exit; use structopt::StructOpt; +use cli::Arguments; +use current_weater::CurrentWeather; + fn main() { - let opts = Options::from_args(); + let opts = Arguments::from_args(); match opts { - Options::CurrentWeather { + Arguments::CurrentWeather { latitude, longitude, + all, is_day, temperature, windspeed, winddirection, clean, } => { - let result = extract_weather(latitude, longitude); - let weather = result.expect("Error requesting weather"); + if !all && !is_day && !temperature && !windspeed && !winddirection { + eprintln!("[ERROR] Please provide at least one parameter to print"); + exit(1); + } - let mut final_string_vec: Vec = Vec::new(); + let result = extract_weather(latitude, longitude); + let mut weather = result.unwrap_or_else(|_| { + eprintln!("[ERROR] Requesting current_weather for Latitude: {latitude}, Longitude: {longitude}"); + exit(1); + }); + + let mut string_vec: Vec = Vec::new(); if !clean { - final_string_vec.push(format!( + string_vec.push(format!( "=== Current weather for Latitude: {latitude}, Longitude: {longitude} ===" )); } - // TODO: Check if any flag has been selected. - let current_weather = &weather["current_weather"]; - if is_day { - let is_day = ¤t_weather["is_day"] == 1; - if clean { - final_string_vec.push(format!("{is_day}")); - } else { - final_string_vec.push(format!("Is day: {is_day}")); - } + let current_weather_data = weather["current_weather"].take(); + let current_weather = CurrentWeather::new(current_weather_data, clean); + + if is_day || all { + string_vec.push(current_weather.extract_data("is_day", "Is day")); } - if temperature { - let temperature = ¤t_weather["temperature"]; - if clean { - final_string_vec.push(format!("{temperature}")); - } else { - final_string_vec.push(format!("Temperature: {temperature}")); - } + if temperature || all { + string_vec.push(current_weather.extract_data("temperature", "Temperature")); } - if windspeed { - let windspeed = ¤t_weather["windspeed"]; - if clean { - final_string_vec.push(format!("{windspeed}")); - } else { - final_string_vec.push(format!("Wind speed: {windspeed}")); - } + if windspeed || all { + string_vec.push(current_weather.extract_data("windspeed", "Wind speed")); } - if winddirection { - let winddirection = ¤t_weather["winddirection"]; - if clean { - final_string_vec.push(format!("{winddirection}")); - } else { - final_string_vec.push(format!("Wind direction: {winddirection}")); - } + if winddirection || all { + string_vec.push(current_weather.extract_data("winddirection", "Wind direction")); } if clean { - let final_string = final_string_vec.join(","); + let final_string = string_vec.join(","); println!("{final_string}"); } else { - let final_string = final_string_vec.join("\n"); + let final_string = string_vec.join("\n"); println!("{final_string}"); } } @@ -78,15 +72,5 @@ fn main() { fn extract_weather(latitude: f32, longitude: f32) -> Result { let url = format!("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true"); let body: serde_json::Value = ureq::get(&url).call()?.into_json()?; - - // TODO: We can also add this data. - // let elevation = &body["elevation"]; - // println!("[D] Elevation: {elevation}"); - // let timezone = &body["timezone"]; - // println!("[D] Timezone: {timezone}"); - - // let current_weather = &body["current_weather"]; - // let time = ¤t_weather["time"]; - // println!("[D] Time: {time}"); Ok(body) }