lib/choir/src/composition/module/serialization/codec.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const model = @import("../root.zig");
3 const serialization = @import("root.zig");
4 const format = serialization.format;
5 const source = serialization.source;
6 const fragment = serialization.fragment;
7 const variant = serialization.variant;
8 const SerializeError = serialization.SerializeError;
9 const DeserializeError = serialization.DeserializeError;
10
11 pub fn serialize(
12 allocator: std.mem.Allocator,
13 module: *const model.CompositionModule,
14 ) SerializeError![]u8 {
15 try module.verify();
16 var manifests = serialization.reference.Manifests{};
17 for (module.fragments.items) |fragment_value| {
18 _ = try manifests.intern(fragment_value.pipeline_input.record.compilerManifest());
19 }
20 var writer = try format.initWriter(allocator);
21 errdefer writer.deinit();
22 try source.write(&writer, &module.source_module);
23 try serialization.reference.writeManifests(&writer, &manifests);
24 try writer.writeCount(module.fragments.items.len);
25 for (module.fragments.items) |fragment_value| {
26 try fragment.write(&writer, fragment_value, &manifests);
27 }
28 try writer.writeCount(module.variants.items.len);
29 for (module.variants.items) |variant_value| try variant.write(&writer, variant_value);
30 return try format.finishWriter(&writer);
31 }
32
33 pub fn deserialize(
34 allocator: std.mem.Allocator,
35 bytes: []const u8,
36 ) DeserializeError!model.CompositionModule {
37 var reader = try format.readPayload(bytes);
38 var source_module = try source.read(allocator, &reader);
39 var source_owned = true;
40 errdefer if (source_owned) source_module.deinit();
41 var module = model.CompositionModule{
42 .allocator = allocator,
43 .source_module = source_module,
44 };
45 source_owned = false;
46 errdefer module.deinit();
47
48 const manifests = try serialization.reference.readManifests(&reader);
49 const fragment_count = try reader.readCount();
50 const records = try serialization.reference.createStore(allocator, fragment_count);
51 defer records.release();
52 for (0..fragment_count) |_| {
53 try fragment.read(allocator, &reader, &module, records, &manifests);
54 }
55 const variant_count = try reader.readCount();
56 for (0..variant_count) |_| try variant.read(allocator, &reader, &module);
57 if (!reader.atEnd()) return error.TrailingBytes;
58 try module.verify();
59 return module;
60 }