Adding SpeedUnit and TempUnit
This commit is contained in:
parent
09df3cc6ed
commit
cd04da0d91
@ -3,7 +3,7 @@ name = "open-meteo-cli"
|
||||
description = "CLI to extract meteorology data from Open Meteo"
|
||||
license = "MIT"
|
||||
authors = ["Midefos <midefos@gmail.com>"]
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
edition = "2021"
|
||||
repository = "https://git.midefos.com/midefos/open-meteo-cli/"
|
||||
readme = "README.md"
|
||||
|
10
README.md
10
README.md
@ -9,19 +9,21 @@ CLI to extract meteorology data from Open Meteo.
|
||||
Displays the current weather for your IP address automatically or for specific coordinates.
|
||||
|
||||
```
|
||||
open-meteo-cli current-weather [OPTIONS] --latitude <LATITUDE> --longitude <LONGITUDE>
|
||||
open-meteo-cli current-weather [FLAGS] [OPTIONS]
|
||||
```
|
||||
|
||||
#### Options
|
||||
- `-l, --latitude <LATITUDE>`: Latitude as a decimal number.
|
||||
- `-L, --longitude <LONGITUDE>`: Longitude as a decimal number.
|
||||
- `--temperature-unit <temperature-unit>`: Switches between Celsius or Fahrenheit. Default value is Celsius.
|
||||
- `--speed-unit <speed-unit>`: Switches between km/h, m/s, mp/h or knots. Default value is Kmh.
|
||||
|
||||
#### Flags
|
||||
- `-a, --all`: Displays all the information.
|
||||
- `-d, --is-day`: Displays if it's day or night.
|
||||
- `-t, --temperature`: Displays the decimal temperature, in Celsius.
|
||||
- `-w, --windspeed`: Displays the decimal wind speed, in km/h.
|
||||
- `-W, --winddirection`: Displays the wind direction, in degrees.
|
||||
- `-t, --temperature`: Displays the decimal temperature.
|
||||
- `-w, --windspeed`: Displays the decimal wind speed.
|
||||
- `-W, --winddirection`: Displays the wind direction.
|
||||
- `--coords`: Displays the latitude and the longitude.
|
||||
- `--city`: Displays the city.
|
||||
- `-c, --clean`: Cleans the output and only displays the values separated by commas.
|
||||
|
18
src/cli.rs
18
src/cli.rs
@ -1,5 +1,7 @@
|
||||
use structopt::StructOpt;
|
||||
|
||||
use crate::{temp_unit::TempUnit, speed_unit::SpeedUnit};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "open-meteo-cli",
|
||||
@ -30,14 +32,18 @@ pub enum Arguments {
|
||||
all: bool,
|
||||
#[structopt(short = "d", long, help = "Displays if it's day or night")]
|
||||
is_day: bool,
|
||||
#[structopt(
|
||||
short = "t",
|
||||
long,
|
||||
help = "Displays the decimal temperature, in Celsius"
|
||||
)]
|
||||
#[structopt(short = "t", long, help = "Displays the decimal temperature")]
|
||||
temperature: bool,
|
||||
#[structopt(short = "w", long, help = "Displays the decimal wind speed, in km/h")]
|
||||
#[structopt(long,
|
||||
possible_values = &TempUnit::variants(), default_value = "Celsius" , case_insensitive = true,
|
||||
help = "Switches between Celsius or Fahrenheit")]
|
||||
temperature_unit: TempUnit,
|
||||
#[structopt(short = "w", long, help = "Displays the decimal wind speed")]
|
||||
windspeed: bool,
|
||||
#[structopt(long,
|
||||
possible_values = &SpeedUnit::variants(), default_value = "Kmh" , case_insensitive = true,
|
||||
help = "Switches between km/h, m/s, mp/h or knots")]
|
||||
speed_unit: SpeedUnit,
|
||||
#[structopt(short = "W", long, help = "Displays the wind direction, in degrees")]
|
||||
winddirection: bool,
|
||||
#[structopt(long = "coords", help = "Displays the latitude and the longitude")]
|
||||
|
@ -1,8 +1,12 @@
|
||||
use crate::{speed_unit::SpeedUnit, temp_unit::TempUnit};
|
||||
|
||||
pub struct CurrentWeatherPrintParams {
|
||||
pub all: bool,
|
||||
pub is_day: bool,
|
||||
pub temperature: bool,
|
||||
pub temperature_unit: TempUnit,
|
||||
pub windspeed: bool,
|
||||
pub speed_unit: SpeedUnit,
|
||||
pub winddirection: bool,
|
||||
pub include_coords: bool,
|
||||
pub include_city: bool,
|
||||
@ -14,7 +18,9 @@ impl CurrentWeatherPrintParams {
|
||||
all: bool,
|
||||
is_day: bool,
|
||||
temperature: bool,
|
||||
temperature_unit: TempUnit,
|
||||
windspeed: bool,
|
||||
speed_unit: SpeedUnit,
|
||||
winddirection: bool,
|
||||
include_coords: bool,
|
||||
include_city: bool,
|
||||
@ -24,7 +30,9 @@ impl CurrentWeatherPrintParams {
|
||||
all,
|
||||
is_day,
|
||||
temperature,
|
||||
temperature_unit,
|
||||
windspeed,
|
||||
speed_unit,
|
||||
winddirection,
|
||||
include_coords,
|
||||
include_city,
|
||||
|
@ -1,3 +1,5 @@
|
||||
use crate::speed_unit::speed_to_unit_string;
|
||||
use crate::temp_unit::temp_to_unit_string;
|
||||
use crate::{
|
||||
coords::Coordinates, current_weather::CurrentWeather,
|
||||
current_weather_print_params::CurrentWeatherPrintParams,
|
||||
@ -29,16 +31,7 @@ impl CurrentWeatherPrinter {
|
||||
let mut string_vec: Vec<String> = Vec::new();
|
||||
|
||||
if !self.params.clean {
|
||||
let mut title_header: Vec<String> = Vec::new();
|
||||
title_header.push(String::from("=== Current weather"));
|
||||
|
||||
if (self.params.all || self.params.include_city) && self.city.is_some() {
|
||||
title_header.push(String::from("for"));
|
||||
title_header.push(self.city.clone().unwrap());
|
||||
}
|
||||
|
||||
title_header.push(String::from("==="));
|
||||
string_vec.push(title_header.join(" "));
|
||||
string_vec.push(self.create_header());
|
||||
} else {
|
||||
if self.params.all || self.params.include_coords {
|
||||
string_vec.push(self.coords.latitude.to_string());
|
||||
@ -64,8 +57,9 @@ impl CurrentWeatherPrinter {
|
||||
|
||||
if !self.params.clean && (self.params.all || self.params.include_coords) {
|
||||
string_vec.push(format!(
|
||||
"Latitude: {}, Longitude: {}",
|
||||
self.coords.latitude, self.coords.longitude
|
||||
"{}, {}",
|
||||
self.parse_simple_data(&self.coords.latitude.to_string(), "Latitude", None),
|
||||
self.parse_simple_data(&self.coords.longitude.to_string(), "Longitude", None)
|
||||
));
|
||||
}
|
||||
|
||||
@ -73,11 +67,28 @@ impl CurrentWeatherPrinter {
|
||||
let final_string = string_vec.join(",");
|
||||
final_string
|
||||
} else {
|
||||
string_vec.push(String::from("=== Weather data by Open-Meteo.com ==="));
|
||||
string_vec.push(self.create_footer());
|
||||
string_vec.join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
fn create_header(&self) -> String {
|
||||
let mut title_header: Vec<String> = Vec::new();
|
||||
title_header.push(String::from("=== Current weather"));
|
||||
|
||||
if (self.params.all || self.params.include_city) && self.city.is_some() {
|
||||
title_header.push(String::from("for"));
|
||||
title_header.push(self.city.clone().unwrap());
|
||||
}
|
||||
|
||||
title_header.push(String::from("==="));
|
||||
title_header.join(" ")
|
||||
}
|
||||
|
||||
fn create_footer(&self) -> String {
|
||||
String::from("=== Weather data by Open-Meteo.com ===")
|
||||
}
|
||||
|
||||
fn extract_day(&self) -> String {
|
||||
if self.current_weather.is_day == 1 {
|
||||
self.parse_custom_data(&self.current_weather.is_day.to_string(), "Day")
|
||||
@ -90,7 +101,7 @@ impl CurrentWeatherPrinter {
|
||||
self.parse_simple_data(
|
||||
&self.current_weather.temperature.to_string(),
|
||||
"Temperature",
|
||||
Some("°C"),
|
||||
Some(temp_to_unit_string(&self.params.temperature_unit).as_str()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -98,7 +109,7 @@ impl CurrentWeatherPrinter {
|
||||
self.parse_simple_data(
|
||||
&self.current_weather.windspeed.to_string(),
|
||||
"Wind speed",
|
||||
Some(" km/h"),
|
||||
Some(format!(" {}", speed_to_unit_string(&self.params.speed_unit)).as_str()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -131,6 +142,8 @@ impl CurrentWeatherPrinter {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::speed_unit::SpeedUnit;
|
||||
use crate::temp_unit::TempUnit;
|
||||
|
||||
#[test]
|
||||
fn clean_all_data() {
|
||||
@ -140,8 +153,18 @@ mod tests {
|
||||
windspeed: 7.0,
|
||||
winddirection: 90.0,
|
||||
};
|
||||
let params =
|
||||
CurrentWeatherPrintParams::new(true, false, false, false, false, false, false, true);
|
||||
let params = CurrentWeatherPrintParams::new(
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
TempUnit::Celsius,
|
||||
false,
|
||||
SpeedUnit::Kmh,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
let coords = Coordinates::new(5.0, -5.0);
|
||||
let printer = CurrentWeatherPrinter::new(
|
||||
current_weather,
|
||||
@ -161,8 +184,18 @@ mod tests {
|
||||
windspeed: 12.2,
|
||||
winddirection: 150.0,
|
||||
};
|
||||
let params =
|
||||
CurrentWeatherPrintParams::new(false, true, true, true, false, false, false, true);
|
||||
let params = CurrentWeatherPrintParams::new(
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
TempUnit::Celsius,
|
||||
true,
|
||||
SpeedUnit::Kmh,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
let coords = Coordinates::new(12.0, -55.0);
|
||||
let printer = CurrentWeatherPrinter::new(
|
||||
current_weather,
|
||||
@ -182,8 +215,18 @@ mod tests {
|
||||
windspeed: 15.5,
|
||||
winddirection: 118.0,
|
||||
};
|
||||
let params =
|
||||
CurrentWeatherPrintParams::new(true, false, false, false, false, false, false, false);
|
||||
let params = CurrentWeatherPrintParams::new(
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
TempUnit::Celsius,
|
||||
false,
|
||||
SpeedUnit::Kmh,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
let coords = Coordinates::new(5.0, -5.0);
|
||||
let printer = CurrentWeatherPrinter::new(
|
||||
current_weather,
|
||||
@ -207,12 +250,22 @@ mod tests {
|
||||
fn full_basic_data() {
|
||||
let current_weather = CurrentWeather {
|
||||
is_day: 1,
|
||||
temperature: 3.0,
|
||||
windspeed: 22.5,
|
||||
temperature: 55.0,
|
||||
windspeed: 11.5,
|
||||
winddirection: 125.0,
|
||||
};
|
||||
let params =
|
||||
CurrentWeatherPrintParams::new(false, true, true, true, false, false, false, false);
|
||||
let params = CurrentWeatherPrintParams::new(
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
TempUnit::Fahrenheit,
|
||||
true,
|
||||
SpeedUnit::Mph,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
let coords = Coordinates::new(12.15, 0.235);
|
||||
let printer = CurrentWeatherPrinter::new(
|
||||
current_weather,
|
||||
@ -223,8 +276,8 @@ mod tests {
|
||||
|
||||
let output = printer.extract_string();
|
||||
assert!(output.contains("Day"));
|
||||
assert!(output.contains("Temperature: 3°C"));
|
||||
assert!(output.contains("Wind speed: 22.5 km/h"));
|
||||
assert!(output.contains("Temperature: 55°F"));
|
||||
assert!(output.contains("Wind speed: 11.5 mp/h"));
|
||||
assert!(!output.contains("Wind direction: 125°"));
|
||||
assert!(!output.contains("Latitude: 12.15"));
|
||||
assert!(!output.contains("Longitude: 0.235"));
|
||||
|
14
src/main.rs
14
src/main.rs
@ -1,12 +1,13 @@
|
||||
mod cli;
|
||||
mod coords;
|
||||
|
||||
mod current_weather_print_params;
|
||||
mod current_weather;
|
||||
mod current_weather_print_params;
|
||||
mod current_weather_printer;
|
||||
mod ifconfig;
|
||||
mod ip_api;
|
||||
mod open_meteo;
|
||||
mod speed_unit;
|
||||
mod temp_unit;
|
||||
|
||||
use billboard::{Alignment, Billboard};
|
||||
use current_weather_print_params::CurrentWeatherPrintParams;
|
||||
@ -30,7 +31,9 @@ fn main() {
|
||||
all,
|
||||
is_day,
|
||||
temperature,
|
||||
temperature_unit,
|
||||
windspeed,
|
||||
speed_unit,
|
||||
winddirection,
|
||||
include_coords,
|
||||
include_city,
|
||||
@ -84,7 +87,7 @@ fn main() {
|
||||
city = Some(coords["city"].as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let result = request_current_weather(&coordinates);
|
||||
let result = request_current_weather(&coordinates, &temperature_unit, &speed_unit);
|
||||
let current_weather = result.unwrap_or_else(|_| {
|
||||
eprintln!(
|
||||
"[ERROR] Requesting CurrentWeather for Lat: {}, Lon: {}",
|
||||
@ -97,14 +100,17 @@ fn main() {
|
||||
all,
|
||||
is_day,
|
||||
temperature,
|
||||
temperature_unit,
|
||||
windspeed,
|
||||
speed_unit,
|
||||
winddirection,
|
||||
include_coords,
|
||||
include_city,
|
||||
clean,
|
||||
);
|
||||
|
||||
let current_weather_printer = CurrentWeatherPrinter::new(current_weather, print_params, coordinates, city);
|
||||
let current_weather_printer =
|
||||
CurrentWeatherPrinter::new(current_weather, print_params, coordinates, city);
|
||||
let output = current_weather_printer.extract_string();
|
||||
if clean {
|
||||
println!("{output}");
|
||||
|
@ -1,9 +1,18 @@
|
||||
use crate::{coords::Coordinates, current_weather::CurrentWeather};
|
||||
use crate::{
|
||||
coords::Coordinates,
|
||||
current_weather::CurrentWeather,
|
||||
speed_unit::{speed_to_string, SpeedUnit},
|
||||
temp_unit::{temp_to_string, TempUnit},
|
||||
};
|
||||
|
||||
pub fn request_current_weather(coords: &Coordinates) -> Result<CurrentWeather, ureq::Error> {
|
||||
pub fn request_current_weather(
|
||||
coords: &Coordinates,
|
||||
temp_unit: &TempUnit,
|
||||
speed_unit: &SpeedUnit,
|
||||
) -> Result<CurrentWeather, ureq::Error> {
|
||||
let url = format!(
|
||||
"https://api.open-meteo.com/v1/forecast?latitude={}&longitude={}¤t_weather=true",
|
||||
coords.latitude, coords.longitude
|
||||
"https://api.open-meteo.com/v1/forecast?latitude={}&longitude={}&temperature_unit={}&windspeed_unit={}¤t_weather=true",
|
||||
coords.latitude, coords.longitude, temp_to_string(temp_unit), speed_to_string(speed_unit)
|
||||
);
|
||||
let mut body: serde_json::Value = ureq::get(&url).call()?.into_json()?;
|
||||
let current_weather = body["current_weather"].take();
|
||||
|
30
src/speed_unit.rs
Normal file
30
src/speed_unit.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use structopt::clap::arg_enum;
|
||||
|
||||
arg_enum! {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SpeedUnit {
|
||||
Kmh,
|
||||
Ms,
|
||||
Mph,
|
||||
Knots
|
||||
}
|
||||
}
|
||||
|
||||
pub fn speed_to_unit_string(speed_unit: &SpeedUnit) -> String {
|
||||
match speed_unit {
|
||||
SpeedUnit::Kmh => "km/h".to_string(),
|
||||
SpeedUnit::Ms => "m/s".to_string(),
|
||||
SpeedUnit::Mph => "mp/h".to_string(),
|
||||
SpeedUnit::Knots => "knots".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn speed_to_string(speed_unit: &SpeedUnit) -> String {
|
||||
match speed_unit {
|
||||
SpeedUnit::Kmh => "kmh".to_string(),
|
||||
SpeedUnit::Ms => "ms".to_string(),
|
||||
SpeedUnit::Mph => "mph".to_string(),
|
||||
SpeedUnit::Knots => "kn".to_string(),
|
||||
}
|
||||
}
|
24
src/temp_unit.rs
Normal file
24
src/temp_unit.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use structopt::clap::arg_enum;
|
||||
|
||||
arg_enum! {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TempUnit {
|
||||
Celsius,
|
||||
Fahrenheit
|
||||
}
|
||||
}
|
||||
|
||||
pub fn temp_to_unit_string(temp_unit: &TempUnit) -> String {
|
||||
match temp_unit {
|
||||
TempUnit::Celsius => "°C".to_string(),
|
||||
TempUnit::Fahrenheit => "°F".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn temp_to_string(temp_unit: &TempUnit) -> String {
|
||||
match temp_unit {
|
||||
TempUnit::Celsius => "celsius".to_string(),
|
||||
TempUnit::Fahrenheit => "fahrenheit".to_string(),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user