hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit a553585aca98e1ba0a3ce4fbc62ded353d7d6ea3
parent c3bc4fb27054eb6a7aaa7e75ab6285f47d44a6c5
Author: triesap <tyson@radroots.org>
Date:   Mon, 21 Sep 2026 12:56:35 +0000

core: add price and currency types

Diffstat:
Asrc/hyf_core/domain/price.mojo | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_domain.mojo | 27+++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/src/hyf_core/domain/price.mojo b/src/hyf_core/domain/price.mojo @@ -0,0 +1,67 @@ +from std.collections import Optional + + +@fieldwise_init +struct Price(Copyable, Movable): + var state: String + var amount: Int + var scale: Int + var currency: String + var basis: String + + +def known_price( + amount: Int, scale: Int, currency: String, basis: String +) raises -> Price: + if scale < 0 or scale > 9: + raise Error("price scale must be between 0 and 9") + if currency.strip() == "": + raise Error("known price requires a currency") + if ( + basis != "per_unit" + and basis != "per_pack" + and basis != "per_order" + ): + raise Error("price basis must be per_unit, per_pack or per_order") + if amount < 0: + raise Error("price amount must be non-negative") + return Price( + state="known", + amount=amount, + scale=scale, + currency=String(currency), + basis=String(basis), + ) + + +def unknown_price() -> Price: + return Price( + state="unknown", amount=0, scale=0, currency="", basis="unknown" + ) + + +def price_is_known(price: Price) -> Bool: + return price.state == "known" + + +def price_compare(left: Price, right: Price) raises -> Int: + if not price_is_known(left) or not price_is_known(right): + raise Error("cannot compare unknown prices") + if left.currency != right.currency: + raise Error( + "cannot compare prices in different currencies without conversion" + ) + if left.basis != right.basis: + raise Error("cannot compare prices with different bases") + var scale = left.scale if left.scale > right.scale else right.scale + var left_value = left.amount + var right_value = right.amount + for _ in range(scale - left.scale): + left_value *= 10 + for _ in range(scale - right.scale): + right_value *= 10 + if left_value < right_value: + return -1 + if left_value > right_value: + return 1 + return 0 diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo @@ -197,3 +197,30 @@ def test_normalization_preserves_approximation() raises: assert_equal(normalized.unit, "kg") var exact = new_quantity(80, 0, "lb", "mass", "exact") assert_equal(normalize_quantity_with_rule(exact, rule).qualifier, "exact") + + +from hyf_core.domain.price import ( + known_price, + price_compare, + price_is_known, + unknown_price, +) + + +def test_price_unknown_distinct_from_zero_and_no_fx() raises: + var unknown = unknown_price() + assert_true(not price_is_known(unknown)) + assert_equal(unknown.amount, 0) + var zero = known_price(0, 2, "CAD", "per_unit") + assert_true(price_is_known(zero)) + var five = known_price(500, 2, "CAD", "per_unit") + assert_equal(price_compare(five, zero), 1) + with assert_raises(): + _ = price_compare(five, unknown) + var usd = known_price(500, 2, "USD", "per_unit") + with assert_raises(): + _ = price_compare(five, usd) + with assert_raises(): + _ = known_price(1, 2, "", "per_unit") + with assert_raises(): + _ = known_price(1, 2, "CAD", "per_kg_approx")