Skip to content

Commit e62b440

Browse files
authored
✨ add first release candidate changes (#75)
1 parent a31e707 commit e62b440

19 files changed

+603
-396
lines changed

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ categories = ["command-line-utilities"]
1313

1414
[dependencies]
1515
anyhow = "1.0"
16-
chrono = { version = "0.4", default-features = false, features = ["clock", "unstable-locales"] }
16+
chrono = { version = "0.4", default-features = false, features = [
17+
"clock",
18+
"unstable-locales",
19+
] }
1720
clap = { version = "4.1", default-features = false, features = [
1821
"derive",
1922
"std",

rustfmt.toml

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
hard_tabs = true
22
max_width = 120
33
array_width = 80
4+
fn_call_width = 80
5+
attr_fn_like_width = 80
6+
chain_width = 80
47
struct_lit_width = 36

src/main.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,7 @@ async fn main() -> Result<()> {
1313
let config = Config::get();
1414
let params = Params::merge(&config, &args).await?;
1515

16-
let product = run(&params).await?;
17-
product
18-
.render(
19-
&params.config.forecast,
20-
&params.config.units,
21-
&params.config.gui,
22-
&params.config.language,
23-
&params.texts.weather,
24-
)
25-
.await?;
26-
16+
run(&params).await?.render(&params).await?;
2717
params.handle_next(args, config).await?;
2818

2919
Ok(())

src/modules/args.rs

+23-19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ pub struct Cli {
1313
#[arg(long, short, use_value_delimiter = true, value_name = "FORECAST,...")]
1414
pub forecast: Vec<Forecast>,
1515

16+
// /// [e.g.: -F 2021-01-01]
17+
// #[arg(long, short, use_value_delimiter = true, value_name = "HISTORICAL WEATHER,...")]
18+
// pub historical_weather: Date,
19+
//
1620
/// [e.g.: -u f,12h,in]
1721
#[arg(long, short, use_value_delimiter = true, value_name = "UNIT,...")]
1822
pub units: Vec<UnitArg>,
@@ -30,43 +34,43 @@ pub struct Cli {
3034
pub reset: bool,
3135
}
3236

33-
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, AsRefStr, Serialize, Deserialize)]
37+
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, AsRefStr, Serialize, Deserialize, Hash)]
3438
#[allow(non_camel_case_types)]
3539
pub enum Forecast {
3640
disable,
3741
#[value(name = "(w)eek", aliases = ["w", "week"])]
3842
week,
39-
#[value(name = "(d)ay", aliases = ["d", "day", "today"])]
43+
#[value(name = "to(d)ay", aliases = ["d", "day", "today"])]
4044
day,
41-
// #[value(alias = "monday")]
42-
// mo,
43-
// #[value(alias = "tuesday")]
44-
// tu,
45-
// #[value(alias = "wednesday")]
46-
// we,
47-
// #[value(alias = "thursday")]
48-
// th,
49-
// #[value(alias = "friday")]
50-
// fr,
51-
// #[value(alias = "saturday")]
52-
// sa,
53-
// #[value(alias = "sunday")]
54-
// su,
45+
#[value(aliases = ["mon", "monday"])]
46+
mo,
47+
#[value(aliases = ["tue", "tuesday"])]
48+
tu,
49+
#[value(aliases = ["wed", "wednesday"])]
50+
we,
51+
#[value(aliases = ["thu", "thursday"])]
52+
th,
53+
#[value(aliases = ["fri", "friday"])]
54+
fr,
55+
#[value(aliases = ["sat", "saturday"])]
56+
sa,
57+
#[value(aliases = ["sun", "sunday"])]
58+
su,
5559
}
5660

5761
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, AsRefStr, Serialize, Deserialize)]
5862
#[strum(serialize_all = "snake_case")]
5963
pub enum UnitArg {
60-
// -- Temperature
64+
// Temperature
6165
#[value(name = "(c)elsius", aliases = ["c", "celsius"])]
6266
Celsius,
6367
#[value(name = "(f)ahrenheit", aliases = ["f", "fahrenheit"])]
6468
Fahrenheit,
65-
// -- Windspeed
69+
// Windspeed
6670
Kmh,
6771
Mph,
6872
#[value(name = "(kn)ots", aliases = ["kn", "knots"])]
69-
// serialize as kn for open-meteo api call
73+
// Serialize as kn for open-meteo api call
7074
#[strum(serialize = "kn")]
7175
Knots,
7276
Ms,

src/modules/config.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use ron::{
88
};
99
use serde::{Deserialize, Serialize};
1010
use std::{
11+
collections::HashSet,
1112
fs::{self, File},
1213
io::Write,
1314
path::PathBuf,
@@ -24,7 +25,7 @@ use super::{
2425
pub struct Config {
2526
pub address: String,
2627
pub language: String,
27-
pub forecast: Vec<Forecast>,
28+
pub forecast: HashSet<Forecast>,
2829
#[optional_rename(ConfigFileUnits)]
2930
pub units: Units,
3031
#[optional_rename(ConfigFileGui)]
@@ -35,7 +36,7 @@ impl Default for Config {
3536
fn default() -> Self {
3637
Self {
3738
address: String::new(),
38-
forecast: vec![],
39+
forecast: HashSet::new(),
3940
language: "en_US".to_string(),
4041
units: Units::default(),
4142
gui: Gui::default(),

src/modules/display/current.rs

+32-84
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
use anyhow::Result;
22
use colored::{Color::BrightBlack, Colorize};
33

4-
use crate::modules::{
5-
localization::WeatherLocales,
6-
units::{Time, Units},
7-
};
4+
use crate::modules::params::Params;
85

96
use super::{
107
border::*,
11-
graph::GraphOpts,
12-
gui_config::{ColorOption, Gui},
8+
gui_config::ColorOption,
139
hourly::HourlyForecast,
1410
product::{Product, MIN_WIDTH},
15-
utils::lang_len_diff,
11+
utils::{lang_len_diff, Times},
1612
weathercode::WeatherCode,
1713
wind::WindDirection,
1814
};
@@ -25,10 +21,9 @@ pub struct Current {
2521
dewpoint: String,
2622
wind: String,
2723
pressure: String,
28-
sun_rise: String,
29-
sun_set: String,
24+
sunrise: String,
25+
sunset: String,
3026
wmo_code: WeatherCode,
31-
hourly_forecast: Option<HourlyForecast>,
3227
dimensions: Dimensions,
3328
}
3429

@@ -38,14 +33,7 @@ pub struct Dimensions {
3833
}
3934

4035
impl Current {
41-
pub fn render(
42-
product: &Product,
43-
add_hourly: bool,
44-
units: &Units,
45-
gui: &Gui,
46-
lang: &str,
47-
t: &WeatherLocales,
48-
) -> Result<Dimensions> {
36+
pub fn render(product: &Product, params: &Params, add_hourly: bool) -> Result<Dimensions> {
4937
let Current {
5038
address,
5139
temperature,
@@ -54,20 +42,17 @@ impl Current {
5442
dewpoint,
5543
wind,
5644
pressure,
57-
sun_rise,
58-
sun_set,
45+
sunrise,
46+
sunset,
5947
wmo_code,
60-
hourly_forecast,
6148
dimensions,
62-
} = Self::prepare(product, add_hourly, units, &gui.graph, t)?;
49+
} = Self::prepare(product, params, add_hourly)?;
6350

6451
let Dimensions { width, cell_width } = dimensions;
52+
let (gui, lang) = (&params.config.gui, &params.config.language);
6553

6654
// Border Top
67-
println!(
68-
"{}",
69-
&Edge::Top.fmt(width, &gui.border).color_option(BrightBlack, &gui.color)
70-
);
55+
println!("{}", &Edge::Top.fmt(width, &gui.border).color_option(BrightBlack, &gui.color));
7156

7257
// Address / Title
7358
println!(
@@ -105,28 +90,29 @@ impl Current {
10590
apparent_temperature,
10691
Border::R.fmt(&gui.border).color_option(BrightBlack, &gui.color),
10792
width = width - 2 - lang_len_diff(&apparent_temperature, lang)
93+
// manually account for displacepment of this row until improving the lang_len_diff regex
94+
+ if &lang[..2] == "ja" || &lang[..2] == "ko" { 2 } else { 0 }
10895
);
10996

11097
// Blank Line
11198
println!(
11299
"{}",
113-
Separator::Blank
114-
.fmt(width, &gui.border)
115-
.color_option(BrightBlack, &gui.color)
100+
Separator::Blank.fmt(width, &gui.border).color_option(BrightBlack, &gui.color)
116101
);
117102

118103
// Humidity & Dewpoint
119104
println!(
120105
"{} {: <width$} {}",
121106
Border::L.fmt(&gui.border).color_option(BrightBlack, &gui.color),
122107
format!(
123-
"{: <cell_width$}{}",
108+
"{: <cell_width$} {}",
124109
humidity,
125110
dewpoint,
126111
cell_width = cell_width - lang_len_diff(&humidity, lang)
127112
),
128113
Border::R.fmt(&gui.border).color_option(BrightBlack, &gui.color),
129114
width = width - 2 - lang_len_diff(&humidity, lang) - lang_len_diff(&dewpoint, lang)
115+
+ if &lang[..2] == "ja" || &lang[..2] == "ko" { 3 } else { 0 }
130116
);
131117

132118
// Wind & Pressure
@@ -143,71 +129,45 @@ impl Current {
143129
println!(
144130
"{} {: <cell_width$}{: <width$} {}",
145131
Border::L.fmt(&gui.border).color_option(BrightBlack, &gui.color),
146-
sun_rise,
147-
sun_set,
132+
sunrise,
133+
sunset,
148134
Border::R.fmt(&gui.border).color_option(BrightBlack, &gui.color),
149135
width = width - 2 - cell_width
150136
);
151137

152138
// Hourly Forecast
153-
if let Some(hourly_forecast) = hourly_forecast {
154-
hourly_forecast.render(width, units, &gui.border, &gui.color, t)
139+
if add_hourly {
140+
HourlyForecast::render(&product.weather, params, 0)?;
155141
}
156142

157143
// Border Bottom
158-
println!(
159-
"{}",
160-
Edge::Bottom
161-
.fmt(width, &gui.border)
162-
.color_option(BrightBlack, &gui.color)
163-
);
144+
println!("{}", Edge::Bottom.fmt(width, &gui.border).color_option(BrightBlack, &gui.color));
164145

165146
Ok(dimensions)
166147
}
167148

168-
fn prepare(
169-
product: &Product,
170-
add_hourly: bool,
171-
units: &Units,
172-
graph_opts: &GraphOpts,
173-
t: &WeatherLocales,
174-
) -> Result<Self> {
149+
fn prepare(product: &Product, params: &Params, add_hourly: bool) -> Result<Self> {
175150
let weather = &product.weather;
176151
let address = Product::trunc_address(product.address.clone(), 60);
152+
let t = &params.texts.weather;
177153

178-
// Helpers
179-
let (current_hour, sunrise_hour, sunset_hour) = (
180-
weather.current_weather.time[11..13]
181-
.parse::<usize>()
182-
.unwrap_or_default(),
183-
weather.daily.sunrise[0][11..13].parse::<usize>().unwrap_or_default(),
184-
weather.daily.sunset[0][11..13].parse::<usize>().unwrap_or_default(),
185-
);
186-
let sunrise_time = match units.time {
187-
Time::am_pm => format!("{}:{}am", sunrise_hour, &weather.daily.sunrise[0][14..16]),
188-
_ => weather.daily.sunrise[0][11..16].to_string(),
189-
};
190-
let sunset_time = match units.time {
191-
Time::am_pm => format!("{}:{}pm", sunset_hour - 12, &weather.daily.sunset[0][14..16]),
192-
_ => weather.daily.sunset[0][11..16].to_string(),
193-
};
194-
let night = current_hour < sunrise_hour || current_hour > sunset_hour;
154+
let Times { current_hour, sunrise, sunset, night } = product.weather.get_times(params.config.units.time, 0);
195155

196156
// Display Items
197157
let temperature = format!(
198-
"{}{}",
158+
"{:.1}{}",
199159
weather.current_weather.temperature, weather.hourly_units.temperature_2m
200160
);
201161
let apparent_temperature = format!(
202-
"{} {}{}",
162+
"{} {:.1}{}",
203163
t.feels_like, weather.hourly.apparent_temperature[current_hour], weather.hourly_units.temperature_2m
204164
);
205165
let humidity = format!(
206166
"{}: {}{}",
207167
t.humidity, weather.hourly.relativehumidity_2m[current_hour], weather.hourly_units.relativehumidity_2m,
208168
);
209169
let dewpoint = format!(
210-
"{}: {}{}",
170+
"{}: {:.1}{}",
211171
t.dew_point, weather.hourly.dewpoint_2m[current_hour], weather.hourly_units.dewpoint_2m
212172
);
213173
let wind_direction = WindDirection::get_direction(weather.current_weather.winddirection)?;
@@ -222,28 +182,17 @@ impl Current {
222182
" {}{}",
223183
weather.hourly.surface_pressure[current_hour], weather.hourly_units.surface_pressure
224184
);
225-
let sun_rise = format!(" {sunrise_time}");
226-
let sun_set = format!(" {sunset_time}");
185+
let sunrise = format!(" {sunrise}");
186+
let sunset = format!(" {sunset}");
227187
let wmo_code = WeatherCode::resolve(weather.current_weather.weathercode, night, &t.weather_code)?;
228-
let hourly_forecast = match add_hourly {
229-
true => Some(HourlyForecast::prepare(
230-
weather,
231-
current_hour,
232-
night,
233-
graph_opts,
234-
units,
235-
&t.weather_code,
236-
)?),
237-
_ => None,
238-
};
239188

240189
// Dimensions
241190
let title_width = address.chars().count();
242191
let title_padding = 2 * 2; // 2 spaces on each side
243192
let longest_cell_width = humidity.chars().count();
244193
let dimensions = Dimensions {
245194
width: if add_hourly {
246-
72
195+
super::hourly::WIDTH
247196
} else if title_width > MIN_WIDTH {
248197
title_width + title_padding
249198
} else {
@@ -267,10 +216,9 @@ impl Current {
267216
dewpoint,
268217
wind,
269218
pressure,
270-
sun_rise,
271-
sun_set,
219+
sunrise,
220+
sunset,
272221
wmo_code,
273-
hourly_forecast,
274222
dimensions,
275223
})
276224
}

0 commit comments

Comments
 (0)