rework servicemodel to avoid comptime_string @import

This method was in violation of the accepted proposal
https://github.com/ziglang/zig/issues/2206
and disallowed in the compiler as of adc2aed,
now in 0.8.0.
This commit is contained in:
Emil Lerch 2021-06-30 09:21:08 -07:00
parent dcfefa4072
commit 3c9f91c012
Signed by: lobo
GPG Key ID: A7B62D657EF764F8

View File

@ -1,57 +1,29 @@
const std = @import("std"); const std = @import("std");
const service_list = @import("models/service_manifest.zig");
const expectEqualStrings = std.testing.expectEqualStrings; const expectEqualStrings = std.testing.expectEqualStrings;
pub fn Services(service_imports: anytype) type { pub fn Services(service_imports: anytype) type {
// This service list can be imported from a master file of all services if (service_imports.len == 0)
// provided by codegen return service_list;
const service_list = @import("codegen/service_manifest.zig").services;
// From here, the fields of our structure can be generated at comptime... // From here, the fields of our structure can be generated at comptime...
var fields: [serviceCount(service_list, service_imports)]std.builtin.TypeInfo.StructField = undefined; var fields: [serviceCount(service_imports)]std.builtin.TypeInfo.StructField = undefined;
// This is run at comptime with multiple nested loops and a large (267 at // This is run at comptime with multiple nested loops and a large (267 at
// time of writing) number of services. 4 was chosen by trial and error, // time of writing) number of services. 4 was chosen by trial and error,
// but otherwise the branch count will be the product of field length, // but otherwise the branch count will be the product of field length,
// service list length and the number of imports requested // service list length and the number of imports requested
@setEvalBranchQuota(4 * fields.len * service_list.len * std.math.min(service_imports.len, 1)); // @setEvalBranchQuota(4 * fields.len * service_list.len * std.math.min(service_imports.len, 1));
var inx = 0;
for (fields) |*item, i| { for (fields) |*item, i| {
if (service_imports.len == 0) { const import_service = @field(service_list, @tagName(service_imports[i]));
const import = @field(@import("codegen/models/" ++ service_list[i].file_name), service_list[i].export_name); const import_field = @field(import_service, @tagName(service_imports[i]));
item.* = .{ item.* = .{
.name = service_list[i].name, .name = @tagName(service_imports[i]),
.field_type = @TypeOf(import), .field_type = @TypeOf(import_field),
.default_value = import, .default_value = import_field,
.is_comptime = false, .is_comptime = false,
.alignment = 0, .alignment = 0,
}; };
continue;
}
var found = false;
// we will loop through the big list and check each service
// against the list of desired imports
while (inx < service_list.len) {
for (service_imports) |si| {
if (std.mem.eql(u8, @tagName(si), service_list[inx].name)) {
const import = @field(@import("codegen/models/" ++ service_list[inx].file_name), service_list[inx].export_name);
item.* = .{
.name = service_list[inx].name,
.field_type = @TypeOf(import),
.default_value = import,
.is_comptime = false,
.alignment = 0,
};
found = true;
break;
}
}
inx = inx + 1; // service found or not in list - move to next service
if (found) break;
}
if (!found)
@compileError("imported service(s) not found");
} }
// finally, generate the type // finally, generate the type
@ -65,8 +37,8 @@ pub fn Services(service_imports: anytype) type {
}); });
} }
fn serviceCount(service_list: anytype, desired_services: anytype) usize { fn serviceCount(desired_services: anytype) usize {
if (desired_services.len == 0) return service_list.len; if (desired_services.len == 0) return @TypeOf(service_list).Struct.fields.len;
return desired_services.len; return desired_services.len;
} }