Skip to content

Instantly share code, notes, and snippets.

@grahamc
Created March 27, 2017 00:00
Show Gist options
  • Save grahamc/c7c2fbffc811c5582e39dae30ab88376 to your computer and use it in GitHub Desktop.
Save grahamc/c7c2fbffc811c5582e39dae30ab88376 to your computer and use it in GitHub Desktop.
{
foo = example "foo";
too = {}: example "too";
bar = {
baz = example "bar.baz";
};
zip = [
{ zop = example "zip.0.zop"; }
{ top = example "zip.1.top"; }
(example "zip.2")
];
} -> {
foo = example "foo";
too = example "too";
"bar.baz" = example "bar.baz";
"zip.0.zop" = example "zip.0.zop";
"zip.1.top" = example "zip.1.top";
"zip.2" = example "zip.2";
}
@7c6f434c
Copy link

About the too line: you want to auto-call all functions with {}? Or you want to apply callPackage? Or what?

@7c6f434c
Copy link

And I really hope that example calls are not something to preserve…

@7c6f434c
Copy link

with (import <nixpkgs> {}).lib;
let
  foldSets = l: fold (n: a: a//n) {} l;
  nameValueSet = name: x: builtins.listToAttrs 
    [(nameValuePair (builtins.toString name) x)];
  countList = l: n: if l == [] then {} else 
    (nameValueSet n (builtins.head l)) // 
       (countList (builtins.tail l) (builtins.add 1 n));
  flattenRecursive = prefix: structure:
    if builtins.isList structure then
      flattenRecursive prefix (countList structure 0)
    else if builtins.isAttrs structure then
      flattenSet (if prefix == "" then "" else prefix + ".") structure
    else if builtins.isFunction structure then
      flattenRecursive prefix (structure {})
    else
      nameValueSet prefix structure;
  flatten = flattenRecursive "";
  recurseFlatten = prefix: x: map 
    (name: flattenRecursive (prefix + name) (builtins.getAttr name x))
    (builtins.attrNames x);
  flattenSet = prefix: x: foldSets (recurseFlatten prefix x);
in
flatten {
  foo = "foo";
  too = {}: "too";
  bar = {
    baz = "bar.baz";
  };
  zip = [
    { zop = "zip.0.zop"; }
    { top = "zip.1.top"; }
    ("zip.2")
  ];
}

{ 
  bar.baz = "bar.baz";
  foo = "foo";
  too = "too";
  zip.0.zop = "zip.0.zop";
  zip.1.top = "zip.1.top";
  zip.2 = "zip.2";
}

@7c6f434c
Copy link

(The output is not a valid input for Nix, I know, but that's what nix-instantiate --eval-only --strict - prints for free…)

@7c6f434c
Copy link

(I wonder if I will get any notifications for your replies…)

@7c6f434c
Copy link

@7c6f434c-test Let's check if mentions work…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment