Functional Weave
Code in Rust

money.compare@1.0.0

impl/rust.rs

1,557 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::math_clamp::clamp;  ← from math.clamp ^1.0.0 · built alongside by fune
use super::money_amount::{assert_same_currency, money, money_from_value, Money};  ← from money.amount ^1.0.0 · built alongside by fune

/// -1, 0 or 1, comparing two amounts of the same currency.
///
/// Refuses mixed currencies: which of GBP 10 and EUR 10 is larger depends on a
/// rate, and a comparison that ignores the currency sorts a list into nonsense.
///
/// # Panics
/// Panics if the two amounts are in different currencies.
pub fn compare_money(a: &Money, b: &Money) -> i64 {
    assert_same_currency(a, b);
    match a.minor.cmp(&b.minor) {
        std::cmp::Ordering::Less => -1,
        std::cmp::Ordering::Equal => 0,
        std::cmp::Ordering::Greater => 1,
    }
}

/// The smaller amount; the first when they are equal.
pub fn min_money(a: &Money, b: &Money) -> Money {
    if compare_money(b, a) < 0 { b.clone() } else { a.clone() }
}

/// The larger amount; the first when they are equal.
pub fn max_money(a: &Money, b: &Money) -> Money {
    if compare_money(b, a) > 0 { b.clone() } else { a.clone() }
}

/// `amount` held within `min..=max`, all three in one currency.
///
/// # Panics
/// Panics on mixed currencies or if `min` is above `max`.
pub fn clamp_money(amount: &Money, min: &Money, max: &Money) -> Money {
    assert_same_currency(amount, min);
    assert_same_currency(amount, max);
    money(clamp(amount.minor, min.minor, max.minor), &amount.currency)
}

pub fn fune_vector(args: &[Value]) -> Value {
    Value::Int(compare_money(
        &money_from_value(&args[0]),
        &money_from_value(&args[1]),
    ))
}