Last active
December 26, 2021 11:35
-
-
Save whokilleddb/52266c99378196edb5d97b272f05fbfe to your computer and use it in GitHub Desktop.
Rust Program To Give You Weather Stats Using openweathermap.org
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "forecast" | |
version = "0.1.0" | |
authors = ["whokilleddb <whokilleddb@gmail.com>"] | |
edition = "2018" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
structopt = "0.3.15" | |
exitfailure = "0.5.1" | |
reqwest = { version = "0.10.6", features = ["json"] } | |
serde = "1.0.114" | |
serde_json = "1.0.56" | |
serde_derive = "1.0.114" | |
tokio = { version = "0.2.21", features = ["full"]} | |
tabled = "0.3.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ cargo build --release | |
$ API_KEY=YOUR-API-KEY ./target/release/forecast London UK | |
+--------------+---------+ | |
| City | London | | |
+--------------+---------+ | |
| Country Code | UK | | |
+--------------+---------+ | |
| Latitude | 51.5085 | | |
+--------------+---------+ | |
| Longitude | -0.1257 | | |
+--------------+---------+ | |
| Clouds | mist | | |
+--------------+---------+ | |
| Temperature | 8.10°C | | |
+--------------+---------+ | |
| Humidity | 97 | | |
+--------------+---------+ | |
| Pressure | 1001 | | |
+--------------+---------+ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use structopt::StructOpt; | |
use exitfailure::{ExitFailure}; | |
use serde_derive::{Deserialize, Serialize}; | |
use std::env; | |
use std::process; | |
use reqwest::Url; | |
use tabled::{Tabled, Table}; | |
use tabled::Disable; | |
#[derive(StructOpt)] | |
struct Cli { | |
city: String, | |
country_code: String, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Coord{ | |
lon: f64, | |
lat: f64, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Weather{ | |
details: Details | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Details{ | |
id: i32, | |
main: String, | |
description: String, | |
icon: String, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Temps{ | |
temp: f64, | |
feels_like: f64, | |
temp_min: f64, | |
temp_max: f64, | |
pressure: i32, | |
humidity: i32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Wind{ | |
speed: f64, | |
deg: i32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Clouds{ | |
all: i32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Sys{ | |
r#type: f64, | |
id: i32, | |
country: String, | |
sunrise: i32, | |
sunset: i32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
struct Forecast{ | |
coord: Coord, | |
weather: Weather, | |
base: String, | |
main: Temps, | |
visibility: i32, | |
wind: Wind, | |
clouds: Clouds, | |
dt: i32, | |
sys: Sys, | |
timezone: i32, | |
id: i32, | |
name: String, | |
cod: i32, | |
} | |
fn exit_on_error(msg: &str) -> !{ // Note the `-> !` here | |
eprintln!("Error: {}", msg); | |
process::exit(-1); | |
} | |
impl Forecast { | |
async fn get(city: &String, country_code: &String, api_key: &String) -> Result<Self, ExitFailure>{ | |
let url: String = format!("http://api.openweathermap.org/data/2.5/weather?q={},{}&appid={}",city, country_code, api_key); | |
let url = Url::parse(&*url)?; | |
let resp = reqwest::get(url) | |
.await? | |
.json::<Forecast>() | |
.await?; | |
Ok(resp) | |
} | |
} | |
#[derive(Tabled)] | |
struct Cell{ | |
param: &'static str, | |
val: String, | |
} | |
#[tokio::main] | |
async fn main() -> Result<(), ExitFailure> { | |
let args = Cli::from_args(); | |
let api_key = match env::var("API_KEY") { | |
Ok(api_key) => api_key, | |
Err(_e) => exit_on_error("API_KEY not set"), | |
}; | |
let response = Forecast::get(&args.city,&args.country_code,&api_key).await?; | |
let cells = vec![ | |
Cell{ | |
param: "City", | |
val: args.city.clone(), | |
}, | |
Cell{ | |
param: "Country Code", | |
val: args.country_code.clone(), | |
}, | |
Cell{ | |
param: "Latitude", | |
val: response.coord.lat.to_string(), | |
}, | |
Cell{ | |
param: "Longitude", | |
val: response.coord.lon.to_string(), | |
}, | |
Cell{ | |
param: "Clouds", | |
val: response.weather.details.description.to_string(), | |
}, | |
Cell{ | |
param: "Temperature", | |
val: format!("{:.1$}°C",(response.main.temp - 273.00),2), | |
}, | |
Cell{ | |
param: "Humidity", | |
val: response.main.humidity.to_string(), | |
}, | |
Cell{ | |
param: "Pressure", | |
val: response.main.pressure.to_string(), | |
} | |
]; | |
let table = Table::new(cells).with(Disable::Row(..1)).to_string(); | |
println!("{}",table); | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment