Simplify down to show-days

This commit is contained in:
Love 2025-01-09 15:44:09 +01:00
parent f501569040
commit c381ed2a79
8 changed files with 130 additions and 54 deletions

4
src/cache/cache.rs vendored
View File

@ -3,8 +3,8 @@ use std::io::{BufReader, BufWriter};
use std::path::{Path, PathBuf};
use super::CacheLine;
use crate::cli::View;
use crate::os::Os;
use crate::View;
#[derive(Debug)]
pub struct Cache {
@ -13,7 +13,7 @@ pub struct Cache {
}
impl Cache {
pub fn load(view: View) -> Option<Self> {
pub fn load(view: &View) -> Option<Self> {
let config_opt = Os::get_current()?.get_config_path();
let mut config_path = match config_opt {
Ok(k) => k,

View File

@ -1,6 +1,6 @@
use clap::{arg, Parser, ValueEnum};
use crate::ecb_url;
use super::{ShowDays, SortBy};
#[derive(Debug, Parser)]
#[command(author, version, about)]
@ -30,7 +30,7 @@ pub struct Cli {
pub force_color: bool,
/// Sort by the currency name (in alphabetical order), or by the rate value (low -> high)
#[arg(value_enum, long = "sort-by", short = 's', default_value_t = SortBy::Currency)]
#[arg(value_enum, long = "sort-by", default_value_t = SortBy::Currency)]
pub sort_by: SortBy,
/// Recalculate to the perspective from an included currency
@ -46,51 +46,8 @@ pub struct Cli {
pub max_decimals: u8,
/// Amount of data
#[arg(value_enum, default_value_t = View::TODAY, long="view", short='v')]
pub view: View,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum SortBy {
Currency,
Rate,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum View {
#[clap(name = "last-day")]
TODAY,
#[clap(name = "last-90-days")]
HistDays90,
#[clap(name = "all-days")]
HistDaysAll,
}
impl View {
pub fn to_ecb_url(&self) -> &'static str {
match self {
View::TODAY => ecb_url::TODAY,
View::HistDays90 => ecb_url::hist::DAYS_90,
View::HistDaysAll => ecb_url::hist::DAYS_ALL,
}
}
pub fn get_name(&self) -> &'static str {
match self {
View::TODAY => "today",
View::HistDays90 => "last-90-days",
View::HistDaysAll => "all-days",
}
}
}
impl SortBy {
pub fn get_comparer(&self) -> fn(&(&str, f64), &(&str, f64)) -> std::cmp::Ordering {
match self {
Self::Currency => |a, b| a.0.cmp(&b.0),
Self::Rate => |a, b| a.1.total_cmp(&b.1),
}
}
#[arg(default_value_t = ShowDays::Days(1), long="show_days", short='s')]
pub show_days: ShowDays,
}
#[derive(Debug, Clone, Copy, ValueEnum)]

7
src/cli/mod.rs Normal file
View File

@ -0,0 +1,7 @@
mod cli_t;
mod since;
mod sort_by;
pub use cli_t::{Cli, FormatOption};
pub use since::ShowDays;
pub use sort_by::SortBy;

54
src/cli/since.rs Normal file
View File

@ -0,0 +1,54 @@
use crate::View;
use std::{fmt, str::FromStr};
#[derive(Debug, Clone, Copy)]
pub enum ShowDays {
Days(usize),
All,
}
impl FromStr for ShowDays {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.eq_ignore_ascii_case("all") {
return Ok(ShowDays::All);
}
s.parse::<usize>().map(ShowDays::Days).map_err(|_| {
format!(
"Invalid value for since: '{}'. Use a positive integer or 'start'.",
s
)
})
}
}
impl fmt::Display for ShowDays {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ShowDays::Days(days) => write!(f, "{}", days),
ShowDays::All => write!(f, "all"),
}
}
}
impl ShowDays {
/// None represents infinity
pub fn to_option(&self) -> Option<usize> {
match self {
ShowDays::Days(d) => Some(*d),
ShowDays::All => None,
}
}
pub fn to_view(&self) -> Option<View> {
match self {
ShowDays::Days(d) => match d {
0 => None,
1 => Some(View::TODAY),
2..=90 => Some(View::HistDays90),
91.. => Some(View::HistDaysAll),
},
ShowDays::All => Some(View::HistDaysAll),
}
}
}

16
src/cli/sort_by.rs Normal file
View File

@ -0,0 +1,16 @@
use clap::ValueEnum;
#[derive(Debug, ValueEnum, Clone)]
pub enum SortBy {
Currency,
Rate,
}
impl SortBy {
pub fn get_comparer(&self) -> fn(&(&str, f64), &(&str, f64)) -> std::cmp::Ordering {
match self {
Self::Currency => |a, b| a.0.cmp(&b.0),
Self::Rate => |a, b| a.1.total_cmp(&b.1),
}
}
}

View File

@ -7,9 +7,11 @@ pub mod os;
pub mod parsing;
pub mod table;
pub mod utils_calc;
mod view;
pub use header_description::HeaderDescription;
pub use holiday::Hollidays;
pub use view::View;
const APP_NAME: &'static str = "ECB-rates";
const DEFAULT_WIDTH: usize = 20;

View File

@ -25,11 +25,14 @@ async fn main() -> ExitCode {
let mut header_description = HeaderDescription::new();
let use_cache = !cli.no_cache;
let mut cache = if use_cache {
Cache::load(cli.view)
} else {
None
let view = match cli.show_days.to_view() {
Some(v) => v,
None => {
eprintln!("It doesn't make any sence to fetch 0 days right?");
return ExitCode::SUCCESS;
}
};
let mut cache = if use_cache { Cache::load(&view) } else { None };
let cache_ok = cache.as_ref().map_or_else(
|| false,
|c| c.get_cache_line().map_or_else(|| false, |cl| cl.is_valid()),
@ -44,7 +47,7 @@ async fn main() -> ExitCode {
.exchange_rate_results
.clone()
} else {
let parsed = match get_and_parse(cli.view.to_ecb_url()).await {
let parsed = match get_and_parse(view.to_ecb_url()).await {
Ok(k) => k,
Err(e) => {
eprintln!("Failed to get/parse data from ECB: {}", e);
@ -102,6 +105,18 @@ async fn main() -> ExitCode {
filter_currencies(&mut parsed, &currencies);
}
parsed.reverse();
let parsed = match cli.show_days.to_option() {
Some(n) => {
if parsed.len() <= n {
parsed.as_slice()
} else {
&parsed[0..n]
}
}
None => parsed.as_slice(),
};
let output = match cli.command {
FormatOption::Json => {
let mut json_values = parsed

25
src/view.rs Normal file
View File

@ -0,0 +1,25 @@
use crate::ecb_url;
pub enum View {
TODAY,
HistDays90,
HistDaysAll,
}
impl View {
pub fn to_ecb_url(&self) -> &'static str {
match self {
Self::TODAY => ecb_url::TODAY,
Self::HistDays90 => ecb_url::hist::DAYS_90,
Self::HistDaysAll => ecb_url::hist::DAYS_ALL,
}
}
pub fn get_name(&self) -> &'static str {
match self {
Self::TODAY => "today",
Self::HistDays90 => "last-90-days",
Self::HistDaysAll => "all-days",
}
}
}