{ lib , options , config , pkgs , ... }: let cfg = config.services.gmnisrv; # from https://github.com/openlab-aux/vuizvui/blob/1576e1025d570851449f6668e0bda2b1b9b21e06/modules/programs/foot/default.nix#L15-L48 # this can be replaced with lib.formats.ini when # https://github.com/NixOS/nixpkgs/pull/118925 is merged cfgFormat = { type = with lib.types; let iniAtom = nullOr (oneOf [ bool int float str ]) // { description = "INI atom (null, bool, int, float, or string)"; }; in (attrsOf (either iniAtom (attrsOf iniAtom))) // { description = '' attribute set of either top-level INI atoms (bool, int, float or string) or attribute sets (sections) of INI atoms ''; }; generate = name: value: let isSection = builtins.isAttrs; topLevel = lib.filterAttrs (_: v: !(isSection v)) value; sections = lib.filterAttrs (_: v: isSection v) value; in pkgs.writeText name '' ${lib.generators.toKeyValue {} topLevel} ${lib.generators.toINI {} sections} ''; }; in { options.services.gmnisrv = { enable = lib.mkEnableOption "Enable the gmnisrv service"; settings = lib.mkOption { type = cfgFormat.type; description = '' Configuration for gmnisrv. See gmnisrv.ini(5) for supported settings. ''; default = { "listen" = lib.mkDefault "0.0.0.0:1965 [::]:1965"; ":tls" = { "store" = lib.mkDefault "${cfg.dataDir}/certs"; }; }; }; package = lib.mkOption { type = lib.types.package; default = pkgs.gmnisrv; description = "gmnisrv package to use"; }; dataDir = lib.mkOption { type = lib.types.str; default = "/var/lib/gemini"; description = "Where gmnisrv should store certs and other data."; }; }; config = lib.mkIf cfg.enable { systemd.services.gmnisrv = { description = "gmnisrv service"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; script = "${cfg.package}/bin/gmnisrv -C ${cfgFormat.generate "gmnisrv.ini" cfg.settings}"; }; }; }