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::energy_price_cap_data::{PRICE_CAP, PRICE_CAP_HISTORY}; ← this capability’s own data, compiled from data/price-cap.json into the same file by fune build
fn is_iso_date(value: &str) -> bool {
let bytes = value.as_bytes();
bytes.len() == 10
&& bytes[4] == b'-'
&& bytes[7] == b'-'
&& bytes.iter().enumerate().all(|(i, b)| i == 4 || i == 7 || b.is_ascii_digit())
}
/// The Ofgem price cap unit rate and standing charge in force on `on_date`.
///
/// # Panics
/// Panics on a malformed date, an unknown fuel or payment method, a payment
/// method with no figures, or a date outside every period carried.
pub fn price_cap(fuel: &str, payment_method: &str, on_date: &str) -> PriceCap {
if !is_iso_date(on_date) {
panic!("onDate must be an ISO date (YYYY-MM-DD), received \"{}\"", on_date);
}
if fuel != "electricity" && fuel != "gas" {
panic!("unknown fuel \"{}\": expected electricity or gas", fuel);
}
if !["direct-debit", "standard-credit", "prepayment"].contains(&payment_method) {
panic!(
"unknown payment method \"{}\": expected direct-debit, standard-credit or prepayment",
payment_method
);
}
let rows: Vec<_> = PRICE_CAP
.iter()
.filter(|r| r.fuel == fuel && r.payment_method == payment_method)
.collect();
if rows.is_empty() {
panic!(
"no price cap figures for {} paid by {}: this version carries GB-average Direct Debit figures only",
fuel, payment_method
);
}
let row = match rows.iter().find(|r| r.valid_from <= on_date && on_date <= r.valid_to) {
Some(row) => row,
None => {
// A pruned build must not answer an old date with a newer cap.
if PRICE_CAP_HISTORY != "full" {
let earliest = rows.iter().map(|r| r.valid_from).min().unwrap();
if on_date < earliest {
panic!(
"no price cap for {}/{} on {}: this build was installed with history={}, so it only carries periods from {}. Reinstall with history=full for older dates.",
fuel, payment_method, on_date, PRICE_CAP_HISTORY, earliest
);
}
}
panic!("no price cap for {}/{} on {}", fuel, payment_method, on_date)
}
};
PriceCap {
fuel: fuel.to_string(),
payment_method: payment_method.to_string(),
region: row.region.to_string(),
unit_rate: row.unit_rate,
standing_charge: row.standing_charge,
vat_basis_points: row.vat_basis_points,
valid_from: row.valid_from.to_string(),
valid_to: row.valid_to.to_string(),
}
}
pub fn price_cap_to_value(p: &PriceCap) -> Value {
Value::obj(vec![
("fuel", Value::str(&p.fuel)),
("paymentMethod", Value::str(&p.payment_method)),
("region", Value::str(&p.region)),
("unitRate", Value::Int(p.unit_rate)),
("standingCharge", Value::Int(p.standing_charge)),
("vatBasisPoints", Value::Int(p.vat_basis_points)),
("validFrom", Value::str(&p.valid_from)),
("validTo", Value::str(&p.valid_to)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
price_cap_to_value(&price_cap(args[0].as_str(), args[1].as_str(), args[2].as_str()))
}