{ lib, config, ... }: let # Returns the uppercased first label or number of a string firstUpperAlnum = str: lib.mapNullable lib.head (builtins.match "[^A-Z0-9]*([A-Z0-9]).*" (lib.toUpper str)); userType = lib.types.submodule ( { name, ... }: { options = { departure = lib.mkOption { type = markerType; default = {}; }; arrival = lib.mkOption { type = markerType; default = {}; }; }; config = { departure.style.label = lib.mkDefault (firstUpperAlnum name); arrival.style.label = lib.mkDefault (firstUpperAlnum name); }; }); markerType = lib.types.submodule { options = { location = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; style = { label = lib.mkOption { type = lib.types.nullOr (lib.types.strMatching "[0-9A-Z]"); default = null; }; color = lib.mkOption { type = colorType; default = "red"; }; size = lib.mkOption { type = lib.types.enum [ "tiny" "small" "medium" "large" ]; default = "medium"; }; }; }; }; colorType = lib.types.either (lib.types.strMatching "0x[0-9A-F]{3}[0-9A-F]{3}?") (lib.types.enum [ "black" "blue" "brown" "gray" "green" "orange" "purple" "red" "white" "yellow" ]); in { imports = [ ./path.nix ]; options = { users = lib.mkOption { type = lib.types.attrsOf userType; }; map.markers = lib.mkOption { type = lib.types.listOf markerType; }; }; config = { users = { manuel = { departure = { location = "Switzerland"; style.size = "small"; }; arrival = { location = "Prague"; }; }; ganondorf.departure = { location = "Argentinia"; style = { color = "green"; }; }; }; map = { markers = lib.filter (marker: marker.location != null) ( lib.concatMap (user: [ user.departure user.arrival ]) (lib.attrValues config.users)); center = lib.mkIf (lib.length config.map.markers >= 1) null; zoom = lib.mkIf (lib.length config.map.markers >= 2) null; }; requestParams = let paramForMarker = marker: let size = { tiny = "tiny"; small = "small"; medium = "mid"; large = null; }.${marker.style.size}; attributes = lib.optional (marker.style.label != null) "label:${marker.style.label}" ++ lib.optional (size != null) "size:${size}" ++ [ "color:${marker.style.color}" "$(${config.scripts.geocode}/bin/geocode ${ lib.escapeShellArg marker.location })" ]; in "markers=\"${lib.concatStringsSep "|" attributes}\""; in builtins.map paramForMarker config.map.markers; }; }