{ lib, ... }: { checks = [ { assertion = lib.registry.predicates.uniqueValue (entry: entry.value.domain); message = "Route domains must be unique."; } { assertion = entries: lib.registry.predicates.uniqueValue (entry: entry.value) ( lib.concatMap (entry: map (port: entry // { value = port; }) entry.value.udp.ports) entries ); message = "Route UDP ports must be unique."; } { assertion = entries: lib.all (entry: entry.value.port == null || entry.value.http.port == null) entries; message = "Route entries must not set both port and http.port."; } ]; type = lib.types.submodule { options = { domain = lib.mkOption { type = lib.types.str; example = "files.alexion.dev"; description = "Domain served by this route entry."; }; port = lib.mkOption { type = lib.types.nullOr lib.types.port; default = null; example = 3923; description = "HTTPS backend TCP port served by the matching address registry entry."; }; http.port = lib.mkOption { type = lib.types.nullOr lib.types.port; default = null; example = 8082; description = "HTTP backend TCP port served by the matching address registry entry."; }; udp.ports = lib.mkOption { type = lib.types.listOf lib.types.port; default = [ ]; example = [ 2456 2457 ]; description = "UDP ports served by the matching address registry entry."; }; }; }; }