pgmql/lib/registry.zig

67 lines
2.4 KiB
Zig

const std = @import("std");
const zzz = @import("zzz");
const _comptime = @import("utils/comptime.zig");
const _api = @import("api.zig");
const _model = @import("model.zig");
const _dispatchers = @import("dispatchers.zig");
const _crud = @import("crud.zig");
/// Build models map, to associate model name to their identifier name.
fn BuildModelsMap(comptime models: type) std.StaticStringMap([]const u8) {
// Build key-values array.
var mapKeyValues: [std.meta.declarations(models).len](struct{[]const u8, []const u8}) = undefined;
// For each model, add its identifier name to the key-values array.
for (&mapKeyValues, std.meta.declarations(models)) |*keyVal, model| {
keyVal.* = .{@field(models, model.name).getIdentifier(), model.name};
}
// Initialize a new static string map and return it.
return std.StaticStringMap([]const u8).initComptime(mapKeyValues);
}
/// Compile-time models registry.
pub fn Registry(comptime models: type, comptime authenticationModelName: []const u8) type {
if (!@hasDecl(models, authenticationModelName))
@compileError("\"" ++ authenticationModelName ++ "\" not found in models definition structure.");
return struct {
const SelfRegistry = @This();
/// Authentication type, induced from the defined authentication model.
pub const AuthenticationType = @field(Models, authenticationModelName).structure();
pub const dispatchers = struct {
/// Create a new dispatcher definition for the current registry.
pub fn Definition(PayloadType: type) type {
return _dispatchers.DispatcherDefinition(AuthenticationType, PayloadType);
}
/// Default CRUD dispatchers definitions for the given model.
pub fn Crud(model: _model.Model) type {
const ModelDispatcherDefinition = Definition(model.structure());
return _crud.Crud(ModelDispatcherDefinition);
}
};
/// Create a new API with this registry and the provided dispatchers definition.
pub fn Api(comptime dispatchersDefinition: type) type {
return _api.Api(SelfRegistry, dispatchersDefinition);
}
/// Defined models.
pub const Models = models;
/// Map models identifiers to models names in the registry.
pub const ModelsMap = BuildModelsMap(models);
/// Get model name from its provided instance.
pub fn getModelName(comptime model: _model.Model) []const u8 {
if (ModelsMap.get(model.getIdentifier())) |modelName| {
return modelName;
} else {
@compileError("undefined model " ++ model.getIdentifier());
}
}
};
}