commit 72042b42bdfe41c1170914d5bcdcf801c40a85f1
parent d82d4a21c8010a39d982560fd6096eef8c0dce62
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 12:56:06 +0000
core: add trusted pack conversion support
Diffstat:
2 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/src/hyf_core/domain/pack.mojo b/src/hyf_core/domain/pack.mojo
@@ -0,0 +1,55 @@
+from hyf_core.domain.quantity import Quantity
+from hyf_core.domain.units import unit_dimension
+
+
+@fieldwise_init
+struct PackRule(Copyable, Movable):
+ var product_id: String
+ var pack_unit: String
+ var inner_unit: String
+ var per_pack_value: Int
+ var per_pack_scale: Int
+ var version: String
+
+
+def pack_rule(
+ product_id: String,
+ pack_unit: String,
+ inner_unit: String,
+ per_pack_value: Int,
+ per_pack_scale: Int,
+ version: String,
+) raises -> PackRule:
+ if product_id.strip() == "" or version.strip() == "":
+ raise Error("pack rule requires product_id and version")
+ if pack_unit.strip() == "" or inner_unit.strip() == "":
+ raise Error("pack rule requires pack_unit and inner_unit")
+ if per_pack_value <= 0:
+ raise Error("pack rule per_pack_value must be positive")
+ if per_pack_scale < 0 or per_pack_scale > 9:
+ raise Error("pack rule per_pack_scale must be between 0 and 9")
+ if unit_dimension(inner_unit) == "unknown":
+ raise Error("pack rule inner_unit dimension is unknown")
+ return PackRule(
+ product_id=String(product_id),
+ pack_unit=String(pack_unit),
+ inner_unit=String(inner_unit),
+ per_pack_value=per_pack_value,
+ per_pack_scale=per_pack_scale,
+ version=String(version),
+ )
+
+
+def apply_pack_conversion(
+ product_id: String, packs: Quantity, rule: PackRule
+) raises -> Quantity:
+ if product_id != rule.product_id:
+ raise Error("pack rule does not apply to product " + product_id)
+ if packs.unit != rule.pack_unit:
+ raise Error("pack rule does not apply to unit " + packs.unit)
+ var result = packs.copy()
+ result.value = packs.value * rule.per_pack_value
+ result.scale = packs.scale + rule.per_pack_scale
+ result.unit = String(rule.inner_unit)
+ result.dimension = String(unit_dimension(rule.inner_unit))
+ return result^
diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo
@@ -163,3 +163,24 @@ def test_unit_conversion_rejects_dimension_mismatch_and_unknown_denominator() ra
with assert_raises():
_ = apply_conversion(new_quantity(1, 0, "kg", "mass", "exact"), kg_rule)
_ = pounds
+
+
+from hyf_core.domain.pack import apply_pack_conversion, pack_rule
+
+
+def test_pack_conversion_known_and_rejections() raises:
+ var boxes = new_quantity(20, 0, "box", "count", "exact")
+ var rule = pack_rule("tomato.roma", "box", "kg", 5, 0, "pack-1")
+ var mass = apply_pack_conversion("tomato.roma", boxes, rule)
+ assert_equal(mass.value, 100)
+ assert_equal(mass.unit, "kg")
+ assert_equal(mass.dimension, "mass")
+
+ with assert_raises():
+ _ = apply_pack_conversion("carrot", boxes, rule)
+ with assert_raises():
+ _ = apply_pack_conversion(
+ "tomato.roma", new_quantity(1, 0, "kg", "mass", "exact"), rule
+ )
+ with assert_raises():
+ _ = pack_rule("tomato.roma", "box", "mystery", 5, 0, "pack-1")