weather_in/
lib.rs

1//! This module defines the CLI struct, command-line argument parsing,
2//! and functions for requesting current weather information.
3
4use clap::Parser;
5use std::error::Error;
6use weather::WeatherInfo;
7
8pub mod weather;
9
10#[derive(Parser, Debug)]
11#[command(author, version, about)]
12#[command(override_usage = "weather-in <LOCATION> [OPTIONS] --api-key <API_KEY>")]
13pub struct Cli {
14    /// The location for which weather information is requested
15    pub location: String,
16
17    /// An optional ISO country code for more accurate weather results
18    #[arg(short, long)]
19    pub isocountry: Option<String>,
20
21    /// The OpenWeather API key for accessing weather data
22    #[arg(short, long)]
23    pub api_key: String,
24}
25
26/// Function to request current weather information.
27///
28/// # Arguments
29///
30/// * `location` - The location for which weather information is requested.
31/// * `country` - An optional country code for more accurate results.
32/// * `api_key` - The API key for accessing weather data.
33///
34/// # Returns
35///
36/// Returns a Result containing WeatherInfo on success, or a Box<dyn Error> on failure.
37pub fn request_current_weather(
38    location: &String,
39    country: &Option<String>,
40    api_key: &String,
41) -> Result<WeatherInfo, Box<dyn Error>> {
42    let country = match country {
43        Some(country) => country,
44        None => "",
45    };
46
47    let url = format!(
48        "https://api.openweathermap.org/data/2.5/weather?q={location},{country}&appid={api_key}&units=metric"
49    );
50
51    let res = reqwest::blocking::get(url)?.json::<WeatherInfo>()?;
52    Ok(res)
53}
54
55#[cfg(test)]
56mod tests {
57    use std::env;
58
59    use super::*;
60
61    #[test]
62    fn test_request_current_weather() {
63        let _ = dotenvy::dotenv();
64
65        let location = String::from("London");
66        let country = Some(String::from("UK"));
67        let api_key = env::var("API_KEY").unwrap();
68
69        let res =
70            request_current_weather(&location, &country, &api_key).expect("Error: No response");
71
72        assert_eq!(res.cod, 200);
73    }
74}