lib/choir/src/composition/module/verification/module.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const model = @import("../root.zig");
2 const product = @import("../../../product/root.zig");
3 const verification = @import("root.zig");
4
5 pub fn verify(module: *const model.CompositionModule) verification.Error!void {
6 try module.source_module.verify();
7 for (module.fragments.items, 0..) |*fragment_value, index| {
8 for (module.fragments.items[0..index]) |previous| {
9 if (previous.id.value == fragment_value.id.value) return error.DuplicateFragment;
10 try verifyCompatibleProductKeys(previous.pipeline_input, fragment_value.pipeline_input);
11 }
12 const partition_value = module.source_module.partition(fragment_value.partition) orelse return error.MissingPartition;
13 if (partition_value.pipeline != fragment_value.pipeline) return error.PipelineMismatch;
14 if (!partition_value.product.eql(fragment_value.pipeline_input.ref)) return error.ProductIdentityMismatch;
15 fragment_value.pipeline_input.validate() catch return error.ProductIdentityMismatch;
16 try verification.fragment.verifyValue(fragment_value);
17 }
18 if (module.variants.items.len == 0) return error.MissingCompositionVariant;
19 for (module.variants.items, 0..) |*variant_value, index| {
20 for (module.variants.items[0..index]) |previous| {
21 if (previous.id.value == variant_value.id.value) return error.DuplicateCompositionVariant;
22 if (previous.choice.asSpec().eql(variant_value.choice.asSpec())) return error.DuplicateTargetChoice;
23 }
24 try verification.variant.verifyValue(module, variant_value);
25 }
26 for (module.fragments.items) |fragment_value| {
27 var referenced = false;
28 for (module.variants.items) |variant_value| {
29 if (variant_value.containsFragment(fragment_value.id)) {
30 referenced = true;
31 break;
32 }
33 }
34 if (!referenced) return error.UnreferencedFragment;
35 }
36 }
37
38 fn verifyCompatibleProductKeys(left: product.ProductKey, right: product.ProductKey) verification.Error!void {
39 if (left.ref.eql(right.ref) and !left.eql(right)) return error.ConflictingProductKey;
40 }