pgmql/lib/api.zig

100 lines
3.5 KiB
Zig

const std = @import("std");
const _registry = @import("registry.zig");
const _model = @import("model.zig");
const _dispatchers = @import("dispatchers.zig");
/// Type of dispatchers map.
pub const DispatchersMap = std.StaticStringMap(_dispatchers.Dispatcher);
/// Type of models dispatchers map.
pub const ModelsDispatchersMap = std.StaticStringMap(DispatchersMap);
/// Build dispatchers maps of all models from the dispatchers definition structure.
fn BuildModelsDispatchersMaps(comptime dispatchersDefinition: type) ModelsDispatchersMap {
return ModelsDispatchersMap.initComptime(comptime dispatchersKv: {
// Get all models dispatchers definition structures.
const modelsDispatchersDecls = std.meta.declarations(dispatchersDefinition);
// Initialize a new key-values array for all models.
var dispatchersKv: [modelsDispatchersDecls.len]struct{[]const u8, DispatchersMap} = undefined;
// Build all dispatchers maps and add them in the key-values array.
for (&dispatchersKv, modelsDispatchersDecls) |*dispatcherKv, modelDispatchersDecl| {
dispatcherKv.* = .{ modelDispatchersDecl.name, BuildDispatchersMap(modelDispatchersDecl.name, @field(dispatchersDefinition, modelDispatchersDecl.name)) };
}
// Return the new dispatchers maps key-values.
break :dispatchersKv dispatchersKv;
});
}
/// Build a dispatchers map for a model from its dispatchers definition structure.
fn BuildDispatchersMap(comptime modelName: []const u8, comptime dispatchersBuilders: type) DispatchersMap {
// Return the new dispatchers map.
return DispatchersMap.initComptime(comptime dispatchersKv: {
// Get all dispatchers declarations.
const dispatchersDecls = std.meta.declarations(dispatchersBuilders);
// Initialize a new key-values array for all dispatchers.
var dispatchersKv: [dispatchersDecls.len]struct{[]const u8, _dispatchers.Dispatcher} = undefined;
// Build all dispatchers and add them in the key-values array.
for (dispatchersKv[0..dispatchersDecls.len], dispatchersDecls) |*dispatcherKv, dispatcherDecl| {
dispatcherKv.* = .{ dispatcherDecl.name, @field(dispatchersBuilders, dispatcherDecl.name).build(modelName, dispatcherDecl.name) };
}
// Return the new dispatchers key-values.
break :dispatchersKv dispatchersKv;
});
}
/// MQL API structure.
pub fn Api(
comptime registry: type,
comptime dispatchersDefinition: type,
) type {
// Build models dispatchers map.
const dispatchersMap = BuildModelsDispatchersMaps(dispatchersDefinition);
// Compute dispatchers array size.
const dispatchersArraySize = comptime dispatchersArraySize: {
var size = 0;
for (dispatchersMap.values()) |dispatchers| {
size += dispatchers.values().len;
}
break :dispatchersArraySize size;
};
// Build dispatchers array.
const dispatchersArray = comptime dispatchersArray: {
var dispatchersArray: [dispatchersArraySize]_dispatchers.Dispatcher = undefined;
var dispatchersArrayIndex = 0;
for (dispatchersMap.values()) |dispatchers| {
for (dispatchers.values()) |dispatcher| {
dispatchersArray[dispatchersArrayIndex] = dispatcher;
dispatchersArrayIndex += 1;
}
}
break :dispatchersArray dispatchersArray;
};
return struct {
pub const Registry = registry;
pub const dispatchers = dispatchersMap;
/// Get model name from its provided instance.
pub fn getModelName(comptime model: _model.Model) []const u8 {
return Registry.getModelName(model);
}
/// Get a list of all declared dispatchers.
pub fn getDispatchers() []const _dispatchers.Dispatcher {
return dispatchersArray[0..dispatchersArraySize];
}
};
}