{ lib }: let inherit (lib) filterAttrs concatStrings concatStringsSep mapAttrsToList concatLists foldlAttrs boolToString ; inherit (builtins) typeOf toString stringLength; # list -> array array = a: "[${concatStringsSep "," (map serialise a)}]"; # attrset -> hashmap _assoc = a: mapAttrsToList (name: val: "${name}: ${val},") a; assoc = a: '' { ${concatStringsSep "\n " (concatLists (map _assoc a))} } ''; stringArray = a: array (map toQuotedString a); tuple = a: "(${concatStringsSep "," (map serialise a)})"; enum = s: if isNull s.value then s.name else concatStrings [ s.name "(" (serialise s.value) ")" ]; option = value: if isNull value then "None" else enum { name = "Some"; inherit value; }; # attrset -> struct _struct_kv = k: v: if v == null then "" else (concatStringsSep ": " [ k (serialise v) ]); _struct_concat = s: foldlAttrs ( acc: k: v: if stringLength acc > 0 then concatStringsSep ", " [ acc (_struct_kv k v) ] else _struct_kv k v ) "" s; _struct_filt = s: _struct_concat (filterAttrs (k: v: v != null) s); struct = s: "(${_struct_filt s})"; toQuotedString = s: ''"${toString s}"''; # this is an enum, but use string interp to make sure it's put in the nix store path = p: ''Path("${p}")''; # attrset for best-effort serialisation of nix types # currently, no way to differentiate between enums and structs serialisers = { int = toString; float = toString; bool = boolToString; # can't assume quoted string, sometimes it's a Rust enum string = toString; path = path; null = _: "None"; set = struct; list = array; }; serialise = v: serialisers.${typeOf v} v; in { inherit array assoc tuple stringArray serialise option path struct toQuotedString enum ; # some handy wrapper types, to reduce transformation effort in modules producing Ron types = { # string type, but implicitly wraps in quote marks for usage in Ron str = (lib.types.coercedTo lib.types.str toQuotedString lib.types.str) // { description = "string"; }; # takes a (non submodule) type, and implicitly wraps in Rust Option<> type option = type: let wantedType = lib.types.nullOr (type); in (lib.types.coercedTo (wantedType) (option) lib.types.str) // { description = wantedType.description; }; }; }