Functional Weave
Code in Python

finance.uk-bank-rate@1.0.1

impl/rust.rs

1,788 bytes · the Rust implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::dates_add_days::add_days;  ← from dates.add-days ^1.0.0 · built alongside by fune
use super::finance_uk_bank_rate_data::{BANK_RATE, BANK_RATE_HISTORY};  ← this capability’s own data, compiled from data/bank-rate.json into the same file by fune build

/// Bank Rate in force on a date: the latest change on or before it.
///
/// # Panics
/// Panics on a malformed date or one before the data begins.
pub fn uk_bank_rate(on_date: &str) -> BankRate {
    add_days(on_date, 0); // validates the date; ISO dates then compare as strings
    for row in BANK_RATE {
        if on_date >= row.valid_from && row.valid_to.map_or(true, |to| on_date <= to) {
            return BankRate {
                basis_points: row.basis_points,
                valid_from: row.valid_from.to_string(),
                valid_to: row.valid_to.map(str::to_string),
            };
        }
    }
    // A history=current build keeps only the rate in force; answering an older
    // date with it would be exactly the wrong answer this data exists to prevent.
    if BANK_RATE_HISTORY != "full" {
        if let Some(earliest) = BANK_RATE.iter().map(|r| r.valid_from).min() {
            if on_date < earliest {
                panic!(
                    "no Bank Rate on {}: this build was installed with history={}, so it only carries rates from {}. Reinstall with history=full for older dates.",
                    on_date, BANK_RATE_HISTORY, earliest
                );
            }
        }
    }
    panic!("no Bank Rate on {}", on_date);
}

pub fn bank_rate_to_value(rate: &BankRate) -> Value {
    Value::obj(vec![
        ("basisPoints", Value::Int(rate.basis_points)),
        ("validFrom", Value::str(&rate.valid_from)),
        ("validTo", rate.valid_to.as_deref().map_or(Value::Null, Value::str)),
    ])
}

pub fn fune_vector(args: &[Value]) -> Value {
    bank_rate_to_value(&uk_bank_rate(args[0].as_str()))
}