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]; } }; }