Skip to content

Instantly share code, notes, and snippets.

@DavHau
Created August 11, 2023 01:20
Show Gist options
  • Save DavHau/568bdff2727b1e959a836849169a6e26 to your computer and use it in GitHub Desktop.
Save DavHau/568bdff2727b1e959a836849169a6e26 to your computer and use it in GitHub Desktop.
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
## IMPLEMENTATION
withNames = names: func:
withNames' names func {};
withNames' = names: func: defaultArgs': arg:
let
defaultArgs = defaultArgs' // { ${lib.head names} = arg; };
in
if builtins.isAttrs arg then
func (defaultArgs' // arg)
else if builtins.length names == 1 then
func defaultArgs
else
withNames' (lib.tail names) func defaultArgs;
## TESTS
original = pkgs.writeTextFile {name = "hello"; text = "world";};
writeText =
withNames ["name" "text" "executable"] pkgs.writeTextFile;
# all args positional
ex1 = writeText "hello" "world" false;
# all args as attrs
ex2 = writeText { name = "hello"; text = "world"; executable = false; };
# mixed positional and attrs
ex3 = writeText "hello" { text = "world"; executable = false; };
# optional args can be ommitted
ex4 = writeText { name = "hello"; text = "world"; };
# ... also when using positional args,
# though`{}` is required to terminate positional args early
ex5 = writeText "hello" "world" {};
## NOT (YET) SUPPORTED
# passt too many args
problem1 = writeText "hello" "world" false { name = "hello"; };
# pass multiple attrset args
problem2 = writeText "hello" { text = "world"; } { executable = false; };
# pass too few args
problem3 = writeText "hello";
in
assert original == ex1 && ex1 == ex2 && ex2 == ex3 && ex3 == ex4 && ex4 == ex5;
"${original}\n${ex1}\n${ex2}\n${ex3}\n${ex4}\n${ex5}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment