armbankrate_parser/
sort.rs

1use std::cmp::Ordering;
2use crate::{Bank, BankImpl, Currency, CurrencyBody, CurrencyName, CurrencyType};
3
4pub fn sort_banks(banks: &mut [Bank], sort_data: &SortData) {
5    banks.sort_by(|a, b| {
6        let (a_currencies, b_currencies): (&CurrencyBody, &CurrencyBody) = currencies_by_type(a, b, &sort_data.currency_type);
7
8        match sort_data.currency_name {
9            CurrencyName::USD => compare(a_currencies.get_usd_rate(), b_currencies.get_usd_rate(), &sort_data.order_type),
10            CurrencyName::GBP => compare(a_currencies.get_gbp_rate(), b_currencies.get_gbp_rate(), &sort_data.order_type),
11            CurrencyName::EUR => compare(a_currencies.get_eur_rate(), b_currencies.get_eur_rate(), &sort_data.order_type),
12            CurrencyName::RUB => compare(a_currencies.get_rub_rate(), b_currencies.get_rub_rate(), &sort_data.order_type),
13        }.reverse()
14    });
15}
16
17fn currencies_by_type<'a>(a: &'a Bank, b: &'a Bank, currency_type: &CurrencyType) -> (&'a CurrencyBody, &'a CurrencyBody) {
18    match currency_type {
19        CurrencyType::Cash => (a.cash_currencies(), b.cash_currencies()),
20        CurrencyType::Noncash => (a.no_cash_currencies(), b.no_cash_currencies())
21    }
22}
23
24fn compare(a: &Currency, b: &Currency, order_type: &OrderType) -> Ordering {
25    let (a, b) = match order_type {
26        OrderType::Buy => (a.buy(), b.buy()),
27        OrderType::Sell => (a.sell(), b.sell()),
28    };
29
30    a.unwrap_or_default().total_cmp(&b.unwrap_or_default())
31}
32
33pub struct SortData {
34    currency_type: CurrencyType,
35    currency_name: CurrencyName,
36    order_type: OrderType,
37}
38
39impl SortData {
40    pub fn new(currency_type: CurrencyType, currency_name: CurrencyName, order_type: OrderType) -> Self {
41        Self {
42            currency_type,
43            currency_name,
44            order_type,
45        }
46    }
47}
48
49pub enum OrderType {
50    Buy,
51    Sell,
52}