armbankrate-parser 0.1.0

Library that parses Armenian bank rates
Documentation
use std::cmp::Ordering;
use crate::{Bank, BankImpl, Currency, CurrencyBody, CurrencyName, CurrencyType};

pub fn sort_banks(banks: &mut [Bank], sort_data: &SortData) {
    banks.sort_by(|a, b| {
        let (a_currencies, b_currencies): (&CurrencyBody, &CurrencyBody) = currencies_by_type(a, b, &sort_data.currency_type);

        match sort_data.currency_name {
            CurrencyName::USD => compare(a_currencies.get_usd_rate(), b_currencies.get_usd_rate(), &sort_data.order_type),
            CurrencyName::GBP => compare(a_currencies.get_gbp_rate(), b_currencies.get_gbp_rate(), &sort_data.order_type),
            CurrencyName::EUR => compare(a_currencies.get_eur_rate(), b_currencies.get_eur_rate(), &sort_data.order_type),
            CurrencyName::RUB => compare(a_currencies.get_rub_rate(), b_currencies.get_rub_rate(), &sort_data.order_type),
        }.reverse()
    });
}

fn currencies_by_type<'a>(a: &'a Bank, b: &'a Bank, currency_type: &CurrencyType) -> (&'a CurrencyBody, &'a CurrencyBody) {
    match currency_type {
        CurrencyType::Cash => (a.cash_currencies(), b.cash_currencies()),
        CurrencyType::Noncash => (a.no_cash_currencies(), b.no_cash_currencies())
    }
}

fn compare(a: &Currency, b: &Currency, order_type: &OrderType) -> Ordering {
    let (a, b) = match order_type {
        OrderType::Buy => (a.buy(), b.buy()),
        OrderType::Sell => (a.sell(), b.sell()),
    };

    a.unwrap_or_default().total_cmp(&b.unwrap_or_default())
}

pub struct SortData {
    currency_type: CurrencyType,
    currency_name: CurrencyName,
    order_type: OrderType,
}

impl SortData {
    pub fn new(currency_type: CurrencyType, currency_name: CurrencyName, order_type: OrderType) -> Self {
        Self {
            currency_type,
            currency_name,
            order_type,
        }
    }
}

pub enum OrderType {
    Buy,
    Sell,
}