commit 86aed9bb1e87e3a532f80b68ced1714e6d4af530
parent 16285c914f21e84bb22f40d95c6ca815171fb1e2
Author: Sylvia Ivory <git@sivory.net>
Date: Mon, 16 Jun 2025 00:37:27 -0700
Implement CLI to test
Diffstat:
5 files changed, 152 insertions(+), 4 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -223,6 +223,10 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fjordgard"
version = "0.1.0"
+dependencies = [
+ "fjordgard-weather",
+ "tokio",
+]
[[package]]
name = "fjordgard-unsplash"
@@ -710,6 +714,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
[[package]]
+name = "lock_api"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -839,6 +853,29 @@ dependencies = [
]
[[package]]
+name = "parking_lot"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -902,6 +939,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
+name = "redox_syscall"
+version = "0.5.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
name = "ref-cast"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1061,6 +1107,12 @@ dependencies = [
]
[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1165,6 +1217,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
+name = "signal-hook-registry"
+version = "1.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "slab"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1362,7 +1423,9 @@ dependencies = [
"bytes",
"libc",
"mio",
+ "parking_lot",
"pin-project-lite",
+ "signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",
diff --git a/Cargo.toml b/Cargo.toml
@@ -10,3 +10,5 @@ version = "0.1.0"
edition = "2024"
[dependencies]
+fjordgard-weather = { version = "0.1.0", path = "crates/weather" }
+tokio = { version = "1.45.1", features = ["full"] }
diff --git a/crates/weather/src/lib.rs b/crates/weather/src/lib.rs
@@ -2,12 +2,13 @@ use std::fmt::Debug;
use reqwest::Client;
-pub use error::*;
+pub use error::Error;
+use error::Result;
use model::*;
use serde::{Serialize, de::DeserializeOwned};
mod error;
-mod model;
+pub mod model;
const USER_AGENT: &str = concat!("fjordgard/", env!("CARGO_PKG_VERSION"));
const GEOCODING_API_HOST: &str = "geocoding-api.open-meteo.com";
diff --git a/crates/weather/src/model.rs b/crates/weather/src/model.rs
@@ -58,6 +58,7 @@ pub struct Location {
#[derive(Deserialize, Debug, Clone)]
pub(crate) struct GeocodeResponse {
+ #[serde(default)]
pub(crate) results: Vec<Location>,
}
diff --git a/src/main.rs b/src/main.rs
@@ -1,3 +1,84 @@
-fn main() {
- println!("Hello, world!");
+use fjordgard_weather::{
+ Error, MeteoClient,
+ model::{CurrentVariable, ForecastOptions, GeocodeOptions},
+};
+
+#[tokio::main]
+async fn main() -> Result<(), Error> {
+ if let Some(location) = std::env::args().nth(1) {
+ let client = MeteoClient::new(None)?;
+
+ let locations = client
+ .geocode(
+ &location,
+ Some(GeocodeOptions {
+ count: Some(1),
+ ..Default::default()
+ }),
+ )
+ .await?;
+
+ match locations.get(0) {
+ None => eprintln!("location not found"),
+ Some(loc) => {
+ println!(
+ "{}{}, {} ({}, {})",
+ loc.name,
+ loc.admin1
+ .as_ref()
+ .map(|s| format!(", {s}"))
+ .unwrap_or_default(),
+ loc.country,
+ loc.latitude,
+ loc.longitude
+ );
+
+ let forecast = client
+ .forecast_single(
+ loc.latitude,
+ loc.longitude,
+ Some(ForecastOptions {
+ current: Some(vec![
+ CurrentVariable::Temperature2m,
+ CurrentVariable::ApparentTemperature,
+ CurrentVariable::RelativeHumidity2m,
+ CurrentVariable::WindSpeed10m,
+ CurrentVariable::WindDirection10m,
+ ]),
+ ..Default::default()
+ }),
+ )
+ .await?;
+ let current = forecast.current.unwrap().data;
+ let current_units = forecast.current_units.unwrap();
+
+ println!(
+ "It is currently {}{} (feels like {}{}) with {}{} humidity",
+ current.get(&CurrentVariable::Temperature2m).unwrap(),
+ current_units.get(&CurrentVariable::Temperature2m).unwrap(),
+ current.get(&CurrentVariable::ApparentTemperature).unwrap(),
+ current_units
+ .get(&CurrentVariable::ApparentTemperature)
+ .unwrap(),
+ current.get(&CurrentVariable::RelativeHumidity2m).unwrap(),
+ current_units
+ .get(&CurrentVariable::RelativeHumidity2m)
+ .unwrap(),
+ );
+ println!(
+ "The wind speed is {}{} pointing {}{}",
+ current.get(&CurrentVariable::WindSpeed10m).unwrap(),
+ current_units.get(&CurrentVariable::WindSpeed10m).unwrap(),
+ current.get(&CurrentVariable::WindDirection10m).unwrap(),
+ current_units
+ .get(&CurrentVariable::WindDirection10m)
+ .unwrap(),
+ );
+ }
+ }
+ } else {
+ eprintln!("location not specified")
+ }
+
+ Ok(())
}