43 lines
2.0 KiB
Nix
43 lines
2.0 KiB
Nix
{ lib ? (import <nixpkgs> {}).lib
|
|
}: let
|
|
/** returns negation of needle's length iff not found */
|
|
indexOf = needle: haystack: let
|
|
len = lib.stringLength needle;
|
|
naiveImpl = i: if lib.substring i len haystack == needle then i else naiveImpl (i + 1);
|
|
cleverImpl = lib.converge
|
|
(i: let
|
|
substr = lib.substring i len haystack;
|
|
in if lib.strings.levenshteinAtMost (len - 1) needle substr
|
|
then if needle == substr then i else i + 1
|
|
else i + len)
|
|
0;
|
|
in if lib.hasInfix needle haystack
|
|
then if len < 85000000 then naiveImpl 0 else cleverImpl # from testing on a ~1600 KLOC file, cleverImpl starts being faster around this point (presumably because it makes fewer allocations)--though it's still only ~600 ms execution time
|
|
else -len;
|
|
/** returns haystack iff not found */
|
|
substringAfter = needle: haystack: lib.substring
|
|
((indexOf needle haystack) + (lib.stringLength needle))
|
|
(lib.stringLength haystack)
|
|
haystack;
|
|
/** returns empty string iff not found */
|
|
substringBefore = needle: haystack: lib.substring 0 (indexOf needle haystack) haystack;
|
|
/**
|
|
* Filters a list `l` by evaluating a predicate on each element and its index (0-based).
|
|
* The predicate callback `f` has same parameters as for `imap0`, but should return a bool,
|
|
* `true` iff the value should be included in the resulting list.
|
|
* The resulting list only includes the filtered-for elements, not their indices.
|
|
*/
|
|
ifilter0 = f: l: lib.pipe l [
|
|
(lib.imap0 (i: v: { inherit i v; }))
|
|
(lib.filter (a: f a.i a.v))
|
|
(lib.catAttrs "v")
|
|
];
|
|
ac = lib.attrNames (import ./.. {}); # could also check shell.nix, but that's completely programmatic and a strict subset of default.nix so there's not much point
|
|
ex = lib.pipe (lib.readFile ./nix_expr_usage_docs.md) [
|
|
(substringAfter "MARKER_FOR_HELPER_SCRIPT_START")
|
|
(substringBefore "MARKER_FOR_HELPER_SCRIPT_END")
|
|
(lib.splitString "`")
|
|
(ifilter0 (i: _: lib.mod i 2 == 1))
|
|
];
|
|
in { missing = lib.subtractLists ac ex; extra = lib.subtractLists ex ac; }
|