]> git.sondrewold.no Git - weather_cli.git/commitdiff
Add draft
authorSondre Wold <[email protected]>
Sat, 6 Apr 2024 14:52:45 +0000 (16:52 +0200)
committerSondre Wold <[email protected]>
Sat, 6 Apr 2024 14:52:45 +0000 (16:52 +0200)
weather_cli/Cargo.toml [new file with mode: 0644]
weather_cli/src/main.rs [new file with mode: 0644]

diff --git a/weather_cli/Cargo.toml b/weather_cli/Cargo.toml
new file mode 100644 (file)
index 0000000..9a87c45
--- /dev/null
@@ -0,0 +1,12 @@
+[package]
+name = "weather_cli"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+lazy_static = "1.4.0"
+reqwest = { version = "0.10", features = ["blocking", "json"] }
+serde = { version = "1", features = ["derive"] }
+serde_json = "1.0.114"
diff --git a/weather_cli/src/main.rs b/weather_cli/src/main.rs
new file mode 100644 (file)
index 0000000..767e260
--- /dev/null
@@ -0,0 +1,119 @@
+use serde::{Deserialize, Serialize};
+use std::env;
+
+struct Config {
+    hours: usize,
+}
+
+impl Config {
+    fn new(args: &[String]) -> Config {
+        let hours = match args[1].clone().parse() {
+            Ok(hours) => hours,
+            Err(error) => panic!(
+                "Failed to provide a digit for the hours argument: {:?}",
+                error
+            ),
+        };
+        Config { hours }
+    }
+}
+
+struct Location {
+    lat: String,
+    lon: String,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct LocationResponse {
+    loc: String,
+}
+
+impl Location {
+    fn new() -> Location {
+        let response = match reqwest::blocking::get("https://ipinfo.io") {
+            Ok(response) => response,
+            Err(error) => panic!("Failed to fetch current location: {:?}", error),
+        };
+
+        let location_response: LocationResponse = match response.json() {
+            Ok(location_response) => location_response,
+            Err(error) => panic!("Failed to parse location response: {:?}", error),
+        };
+        let parsed = location_response.loc.split(",");
+        let collection: Vec<&str> = parsed.collect();
+        Location {
+            lat: String::from(collection[0]),
+            lon: String::from(collection[1]),
+        }
+    }
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Detail {
+    air_temperature: f32,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Details {
+    details: Detail,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Instant {
+    instant: Details,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Data {
+    data: Instant,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Timeseries {
+    timeseries: Vec<Data>,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Properties {
+    properties: Timeseries,
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct YrResponse {
+    properties: Properties,
+}
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    let config: Config = Config::new(&args);
+    let hours: usize = config.hours;
+    let location: Location = Location::new();
+    //println!("Current latitude: {:?}", location.lat);
+    //println!("Current longitude: {:?}", location.lon);
+    let req_str = format!(
+        "https://api.met.no/weatherapi/locationforecast/2.0/compact?lat={}&lon={}",
+        location.lat, location.lon
+    );
+    let response = match reqwest::blocking::get(&req_str) {
+        Ok(response) => response,
+        Err(error) => panic!("Failed to fetch weather data from YR: {:?}", error),
+    };
+    let obj: Properties = match response.json() {
+        Ok(prop) => prop,
+        Err(error) => panic!("Failed to parse json: {:?}", error),
+    };
+    let mut temperatures: f32 = 0.0;
+    for hour in 0..hours {
+        temperatures = temperatures
+            + obj.properties.timeseries[hour]
+                .data
+                .instant
+                .details
+                .air_temperature;
+    }
+    let avg = temperatures / hours as f32;
+    println!(
+        "Average temperature for the next {} hour(s) is going to be {}",
+        hours, avg
+    );
+}