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()); } } }; }