diff --git a/panel/nix/jsonschema-to-module.nix b/panel/nix/jsonschema-to-module.nix new file mode 100644 index 00000000..4eb18ed9 --- /dev/null +++ b/panel/nix/jsonschema-to-module.nix @@ -0,0 +1,81 @@ +{ lib, ... }: + +let + inherit (lib) + fromJSON + mapAttrs + attrValues + concatStringsSep + elem + ; + + option = + required: name: prop: + let + description = + if prop ? description then + '' + description = "${prop.description}"; + '' + else + ""; + default = + if (!elem name required && prop ? default) then + '' + default = ${to-value prop.type prop.description}; + '' + else + ""; + + to-type = + type: + { + string = "str"; + integer = "int"; + boolean = "bool"; + } + .${type} or (throw "Unsupported schema type: ${type}"); + + to-value = + type: value: + { + string = ''"${toString value}"''; + integer = toString value; + boolean = if value then "true" else "false"; + } + .${type} or (throw "Unsupported value type: ${type}"); + in + # TODO: squash + '' + ${name} = mkOption { + ${ + # TODO: indent + description + } + type = types.${to-type prop.type}; + ${ + # TODO: indent + default + } + }; + ''; +in +jsonschema: name: # TODO: can't we get the name from the schema? +let + schema = fromJSON jsonschema; + properties = schema.properties or { }; + required = schema.required or [ ]; + options = concatStringsSep "\n\n" (attrValues (mapAttrs (option required) properties)); +in +# TODO: test this +'' + { lib, ... }: + let + inherit (lib) mkOption types; + in + { + options.services.${name} = { + ${options} + }; + } +''