Functional Weave
Code in TypeScript

insurance.loss-ratio@1.0.1

impl/rust.rs

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

/// Loss, expense and combined ratios against earned premium, in basis points.
///
/// The combined ratio is worked from claims plus expenses, rounded once, not
/// by adding the two rounded ratios, so it can differ from their sum by one
/// basis point: 1.00 and 1.00 on 3.00 are 33.33% each but 66.67% together.
///
/// # Panics
/// Panics on mixed currencies or an earned premium that is not positive.
pub fn loss_ratios(earned_premium: &Money, incurred_claims: &Money, expenses: &Money, mode: &str) -> LossRatios {
    assert_same_currency(earned_premium, incurred_claims);
    assert_same_currency(earned_premium, expenses);
    if earned_premium.minor <= 0 {
        panic!("earnedPremium must be more than zero, received {}", earned_premium.minor);
    }
    let p = earned_premium.minor;
    LossRatios {
        loss_ratio_basis_points: round_div(incurred_claims.minor * 10000, p, mode),
        expense_ratio_basis_points: round_div(expenses.minor * 10000, p, mode),
        combined_ratio_basis_points: round_div((incurred_claims.minor + expenses.minor) * 10000, p, mode),
    }
}

pub fn loss_ratios_to_value(r: &LossRatios) -> Value {
    Value::obj(vec![
        ("lossRatioBasisPoints", Value::Int(r.loss_ratio_basis_points)),
        ("expenseRatioBasisPoints", Value::Int(r.expense_ratio_basis_points)),
        ("combinedRatioBasisPoints", Value::Int(r.combined_ratio_basis_points)),
    ])
}

pub fn fune_vector(args: &[Value]) -> Value {
    loss_ratios_to_value(&loss_ratios(
        &money_from_value(&args[0]),
        &money_from_value(&args[1]),
        &money_from_value(&args[2]),
        args[3].as_str(),
    ))
}