commit 89151e72732976f705881516a78634dcfc5f5ce1
parent aded5b534a068424110a5d07472b65723a9ec55b
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 13:01:52 +0000
core: add coverage and limitation types
Diffstat:
2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/src/hyf_core/domain/coverage.mojo b/src/hyf_core/domain/coverage.mojo
@@ -0,0 +1,43 @@
+from std.collections import List
+
+
+@fieldwise_init
+struct Coverage(Copyable, Movable):
+ var scope: String
+ var truncated: Bool
+ var evaluated: Int
+ var excluded: Int
+ var supported_mode: String
+ var unsupported: List[String]
+
+
+def coverage(
+ truncated: Bool,
+ evaluated: Int,
+ excluded: Int,
+ supported_mode: String,
+ unsupported: List[String],
+) raises -> Coverage:
+ if evaluated < 0 or excluded < 0:
+ raise Error("coverage counts must be non-negative")
+ if supported_mode.strip() == "":
+ raise Error("coverage requires a supported mode")
+ var copied = List[String]()
+ for entry in unsupported:
+ copied.append(String(entry))
+ return Coverage(
+ scope="supplied_only",
+ truncated=truncated,
+ evaluated=evaluated,
+ excluded=excluded,
+ supported_mode=String(supported_mode),
+ unsupported=copied^,
+ )
+
+
+def no_match_is_global_absence() -> Bool:
+ return False
+
+
+def unsupported_is_no_supply() -> Bool:
+ return False
diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo
@@ -525,3 +525,22 @@ def test_plan_conservation_across_lots() raises:
shared.append(allocation("lot-1", "l1", "line-2", 20, 0))
var shared_plan = match_plan("p3", "farm-1", shared)
assert_true(len(plan_conservation_violations(shared_plan, lots)) > 0)
+
+
+from hyf_core.domain.coverage import (
+ Coverage,
+ coverage,
+ no_match_is_global_absence,
+ unsupported_is_no_supply,
+)
+
+
+def test_coverage_limitations_do_not_claim_global_absence() raises:
+ var unsupported = List[String]()
+ unsupported.append("multi_supplier")
+ var value = coverage(True, 10, 2, "single_supplier_compatible_lots", unsupported)
+ assert_equal(value.scope, "supplied_only")
+ assert_true(value.truncated)
+ assert_equal(len(value.unsupported), 1)
+ assert_true(not no_match_is_global_absence())
+ assert_true(not unsupported_is_no_supply())