lib/choir/src/composition/module/verification/fragment.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const artifact = @import("../../../backends/root.zig").artifact;
3 const model = @import("../root.zig");
4 const verification = @import("root.zig");
5
6 pub fn verifySpec(spec: model.FragmentSpec) verification.Error!void {
7 try spec.pipeline_input.validate();
8 if (spec.artifacts.len == 0) return error.MissingArtifact;
9 if (spec.exports.len == 0) return error.MissingExport;
10 for (spec.artifacts) |artifact_value| if (artifact.resource.count(artifact_value) == 0) return error.EmptyArtifact;
11 for (spec.exports, 0..) |export_value, index| {
12 if (export_value.name.len == 0 or export_value.symbol.len == 0) return error.EmptyExport;
13 for (spec.exports[0..index]) |previous| {
14 if (std.mem.eql(u8, previous.name, export_value.name)) return error.DuplicateExport;
15 }
16 }
17 for (spec.imports, 0..) |import_value, index| {
18 if (import_value.name.len == 0 or import_value.symbol.len == 0) return error.EmptyImport;
19 for (spec.imports[0..index]) |previous| {
20 if (std.mem.eql(u8, previous.name, import_value.name)) return error.DuplicateImport;
21 }
22 }
23 }
24
25 pub fn verifyValue(fragment_value: *const model.Fragment) verification.Error!void {
26 try fragment_value.pipeline_input.validate();
27 if (fragment_value.artifacts.len == 0) return error.MissingArtifact;
28 if (fragment_value.exports.len == 0) return error.MissingExport;
29 for (fragment_value.artifacts) |artifact_value| if (artifact.resource.count(artifact_value) == 0) return error.EmptyArtifact;
30 for (fragment_value.exports, 0..) |export_value, index| {
31 if (export_value.name.len == 0 or export_value.symbol.len == 0) return error.EmptyExport;
32 for (fragment_value.exports[0..index]) |previous| {
33 if (std.mem.eql(u8, previous.name, export_value.name)) return error.DuplicateExport;
34 }
35 if (!fragment_value.providesSymbol(export_value.symbol)) return error.MissingProvidedSymbol;
36 }
37 for (fragment_value.imports, 0..) |import_value, index| {
38 if (import_value.name.len == 0 or import_value.symbol.len == 0) return error.EmptyImport;
39 for (fragment_value.imports[0..index]) |previous| {
40 if (std.mem.eql(u8, previous.name, import_value.name)) return error.DuplicateImport;
41 }
42 if (!fragment_value.requiresSymbol(import_value.symbol)) return error.MissingRequiredSymbol;
43 }
44 }