lib/choir/src/composition/plan.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const fixture = @import("fixture/root.zig");
 2 const std = @import("std");
 3 const choir = @import("../root.zig");
 4 const source = @import("source/root.zig");
 5 
 6 const Allocator = std.mem.Allocator;
 7 const product = choir.product;
 8 
 9 /// An owned pipeline proposal for one partition and shared ABI version.
10 /// It retains the exact input record and names an artifact export; native work stays transient.
11 pub const FragmentPlan = struct {
12     allocator: Allocator,
13     id: source.FragmentId,
14     input: source.PipelineInput,
15     export_symbol: []const u8,
16     abi_version: u32,
17 
18     pub fn init(
19         allocator: Allocator,
20         id: source.FragmentId,
21         input: source.PipelineInput,
22         export_symbol: []const u8,
23         abi_version: u32,
24     ) product.ProductMetadataError!FragmentPlan {
25         const input_product = try product.cloneProductKey(allocator, input.product);
26         errdefer product.deinitProductKey(allocator, input_product);
27         return .{
28             .allocator = allocator,
29             .id = id,
30             .input = .{
31                 .partition = input.partition,
32                 .pipeline = input.pipeline,
33                 .product = input_product,
34             },
35             .export_symbol = try allocator.dupe(u8, export_symbol),
36             .abi_version = abi_version,
37         };
38     }
39 
40     pub fn deinit(self: *FragmentPlan) void {
41         self.allocator.free(self.export_symbol);
42         product.deinitProductKey(self.allocator, self.input.product);
43         self.* = undefined;
44     }
45 };
46 
47 test "fragment plan owns product names and export symbol" {
48     const Harness = struct {
49         fn run(allocator: Allocator) !void {
50             const records = try fixture.Records.init(allocator);
51             defer records.deinit();
52             var input_name = [_]u8{ 'i', 'n' };
53             var export_symbol = [_]u8{ 'r', 'u', 'n' };
54             var plan = try FragmentPlan.init(
55                 allocator,
56                 .{ .value = 3 },
57                 .{
58                     .partition = .{ .value = 2 },
59                     .pipeline = .accy,
60                     .product = try records.key(&input_name, "4", "5"),
61                 },
62                 &export_symbol,
63                 1,
64             );
65             defer plan.deinit();
66             input_name[0] = 'x';
67             export_symbol[0] = 'x';
68             try std.testing.expectEqualStrings("in", plan.input.product.ref.stage);
69             try std.testing.expectEqualStrings("run", plan.export_symbol);
70         }
71     };
72 
73     try std.testing.checkAllAllocationFailures(std.testing.allocator, Harness.run, .{});
74 }