From e4b91932f3a91e00d9da5fe211c0c205217e5b6b Mon Sep 17 00:00:00 2001 From: Martin Traverso Date: Tue, 28 Jun 2022 20:09:39 -0300 Subject: [PATCH] Init repo --- Cargo.toml | 12 ++++ README.md | 1 + cities.txt | 1 + src/main.rs | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 cities.txt create mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..51852b5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "clima" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0", features = ["derive"]} +serde_json = "1.0" +reqwest = { version = "0.11", features = ["json"]} +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d8b59e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# accuweathercall diff --git a/cities.txt b/cities.txt new file mode 100644 index 0000000..3d8b59e --- /dev/null +++ b/cities.txt @@ -0,0 +1 @@ +# accuweathercall diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b17e0fc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,157 @@ +use std::env; +use std::fs::File; +use serde::{Serialize, Deserialize}; +use std::string::String; + +#[derive(Debug, Serialize, Deserialize)] +struct City { + name : String, + code: String +} + +#[derive(Debug, Serialize, Deserialize)] +struct Country { + name : String, + flag: String, + cities: Vec +} + +#[derive(Debug, Serialize, Deserialize)] +struct Weather { + #[serde(rename = "Headline")] + headline: Headline, + #[serde(rename = "DailyForecasts")] + daily_forecasts: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +struct Headline { + #[serde(rename = "Text")] + text: String +} + +#[derive(Debug, Serialize, Deserialize)] +struct DailyForecasts { + #[serde(rename = "Date")] + date: String, + #[serde(rename = "Day")] + day: Day, + #[serde(rename = "Night")] + night: Day, + #[serde(rename = "Temperature")] + temperature : Temperature, + #[serde(rename = "Link")] + link: String +} + +#[derive(Debug, Serialize, Deserialize)] +struct Day { + #[serde(rename = "Icon")] + icon: i32, + #[serde(rename = "IconPhrase")] + icon_phrase : String +} + +#[derive(Debug, Serialize, Deserialize)] +struct Temperature { + #[serde(rename = "Minimum")] + minimum: TemperatureValue, + #[serde(rename = "Maximum")] + maximum: TemperatureValue +} + +#[derive(Debug, Serialize, Deserialize)] +struct TemperatureValue { + #[serde(rename = "Value")] + value: f32, + #[serde(rename = "Unit")] + unit: String, + #[serde(rename = "UnitType")] + unit_type: u32, +} + +#[tokio::main] +async fn main() { + let args: Vec = env::args().collect(); + + let key = &args[1]; + let path = &args[2]; + + let countries: Vec = get_list(path.to_string()); + + for country in countries { + println!("{} {}", country.name, country.flag); + for city in country.cities { + println!("{}", city.name); + if let Ok(w) = call_api(&city.code, &key).await { + println!("{}", w.headline.text); + println!("Máxima: {} | Mínima:{}",w.daily_forecasts[0].temperature.maximum.value, w.daily_forecasts[0].temperature.minimum.value); + println!("Día {} ({}) | Noche {} ({})", + convert_icon(w.daily_forecasts[0].day.icon), + w.daily_forecasts[0].day.icon_phrase, + convert_icon(w.daily_forecasts[0].night.icon), + w.daily_forecasts[0].night.icon_phrase, + ); + println!("Más información: {}", w.daily_forecasts[0].link); + println!("***************************"); + } else { + println!("Tan cerca... pero tan lejos. Algo en las estructuras está mal. Quizá nunca debiste ponerte a estudiar RUST. Cagón!"); + } + } + } +} + +// Get all the city and countrie data outside of the program +fn get_list(path:String) -> Vec { + let file = File::open(path).expect("El archivo debería permitir la lectura."); + let json: Vec = serde_json::from_reader(file).expect("Pensá un poquito... capaz que no colocaste la ruta correctamente o peñarol peñarol."); + return json; +} + +// This is the call to the api. +async fn call_api(code:&String, api_key:&String) -> Result { + let url = format!( + "http://dataservice.accuweather.com/forecasts/v1/daily/1day/{}?apikey={}&language=es-ES&metric=true", + code, + api_key); + + let data = reqwest::get(url) + .await? + .json::() + .await?; + + Ok(data) +} + +fn convert_icon(icon: i32) -> String { + + let final_icon = match icon { + 1..=5 => ":soleado:", + 6 => ":casi_todo_soleado:", + 7..=8 => ":nube:", + 35..=38 => ":nube:", + 11 => ":nube:", + 22 => ":nube:", + 12 => ":nube_de_lluvia:", + 13..=14 => ":sol_tras_nubes_lluvia:", + 19 => ":nube_de_nieve:", + 15 => ":nube_de_truenos_y_lluvia:", + 20..=21 => ":sol_con_nubes:", + 23 => ":sol_con_nubes:", + 24 => ":cubito_de_hielo:", + 18 => ":nube_de_lluvia:", + 25 => ":nube_de_lluvia:", + 39..=40 => ":nube_de_lluvia:", + 16..=17 => ":nube_de_truenos_y_lluvia:", + 41..=42 => ":nube_de_truenos_y_lluvia:", + 26 => ":nube_de_nieve:", + 29 => ":nube_de_nieve:", + 30 => ":cara_con_calor:", + 31 => ":cara_con_frio:", + 32 => ":guión:", + 33..=34 => ":luna_llena_con_cara:", + _=>"" + }; + + return final_icon.to_string(); +} \ No newline at end of file