nix-files/modules/lib/default.nix

94 lines
3.2 KiB
Nix

{ lib, ... }:
let
sane-lib = rec {
feeds = import ./feeds.nix { inherit lib; };
fs = import ./fs.nix { inherit lib sane-lib; };
merge = import ./merge.nix { inherit lib sane-lib; };
path = import ./path.nix { inherit lib; };
types = import ./types.nix { inherit lib; };
# re-exports
inherit (merge) mkTypedMerge;
# like `builtins.listToAttrs` but any duplicated `name` throws error on access.
# Type: listToDisjointAttrs :: [{ name :: String, value :: Any }] -> AttrSet
listToDisjointAttrs = l: joinAttrsets (builtins.map nameValueToAttrs l);
# true if p is a prefix of l (even if p == l)
# Type: isPrefixOfList :: [Any] -> [Any] -> bool
isPrefixOfList = p: l: (lib.sublist 0 (lib.length p) l) == p;
# merges N attrsets
# Type: joinAttrsets :: [AttrSet] -> AttrSet
joinAttrsets = l: lib.foldl' lib.attrsets.unionOfDisjoint {} l;
# merges N attrsets, recursively
# Type: joinAttrsetsRecursive :: [AttrSet] -> AttrSet
joinAttrsetsRecursive = l: lib.foldl' (lib.attrsets.recursiveUpdateUntil (path: lhs: rhs: false)) {} l;
# evaluate a `{ name, value }` pair in the same way that `listToAttrs` does.
# Type: nameValueToAttrs :: { name :: String, value :: Any } -> Any
nameValueToAttrs = { name, value }: {
"${name}" = value;
};
# if `maybe-null` is non-null, yield that. else, return the `default`.
withDefault = default: maybe-null: if maybe-null != null then
maybe-null
else
default;
# removes null entries from the provided AttrSet. acts recursively.
# Type: filterNonNull :: AttrSet -> AttrSet
filterNonNull = attrs: lib.filterAttrsRecursive (n: v: v != null) attrs;
# return only the subset of `attrs` whose name is in the provided set.
# Type: filterByName :: [String] -> AttrSet
filterByName = names: attrs: lib.filterAttrs
(name: value: builtins.elem name names)
attrs;
# transform a list into an AttrSet via a function which maps an element to a { name, value } pair.
# it's an error for the same name to be specified more than once
# Type: mapToAttrs :: (a -> { name :: String, value :: Any }) -> [a] -> AttrSet
mapToAttrs = f: list: listToDisjointAttrs (builtins.map f list);
# flatten a nested AttrSet into a list of { path = [String]; value } items.
# the output contains only non-attr leafs.
# so e.g. { a.b = 1; } -> [ { path = ["a" "b"]; value = 1; } ]
# but e.g. { a.b = {}; } -> []
#
# Type: flattenAttrs :: AttrSet[AttrSet|Any] -> [{ path :: String, value :: Any }]
flattenAttrs = flattenAttrs' [];
flattenAttrs' = path: value: if builtins.isAttrs value then (
builtins.concatLists (
lib.mapAttrsToList
(name: flattenAttrs' (path ++ [ name ]))
value
)
) else [
{
inherit path value;
}
];
# like `lib.listFilesRecursive` but does not mangle paths.
#
# Type: enumerateFilePaths :: path -> [String]
enumerateFilePaths = base:
builtins.concatLists (
lib.mapAttrsToList
(name: type:
if type == "directory" then
# enumerate this directory and then prefix each result with the directory's name
builtins.map (e: "${name}/${e}") (enumerateFilePaths (base + "/${name}"))
else
[ name ]
)
(builtins.readDir base)
);
};
in sane-lib