feat(tvix/eval): Implement builtins.listToAttrs

Implement the listToAttrs builtin, which constructs an attribute set
from a list of attribute sets with keys name and value.

This is tested using an adaptation of the nix `eval-ok-listtoattrs.nix`,
with the utilities from `lib.nix` inlined.

Change-Id: Ib5bf743466dda9722c2c1e00797df4b58448cf0f
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6894
Autosubmit: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
Griffin Smith 2022-10-08 14:17:47 -04:00 committed by grfn
parent d0f571dcc0
commit afdf1e0ed0
3 changed files with 33 additions and 0 deletions

View file

@ -294,6 +294,23 @@ fn pure_builtins() -> Vec<Builtin> {
let value = args[0].force(vm)?;
Ok(Value::Bool(matches!(*value, Value::String(_))))
}),
Builtin::new("listToAttrs", &[true], |args: Vec<Value>, vm: &mut VM| {
let list = args[0].to_list()?;
let mut map = BTreeMap::new();
for val in list {
let attrs = val.force(vm)?.to_attrs()?;
let get = |key| {
attrs
.select(key)
.ok_or(ErrorKind::AttributeNotFound { name: key.into() })
};
let name = get("name")?.to_str()?;
let value = get("value")?.clone();
// Map entries earlier in the list take precedence over entries later in the list
map.entry(name).or_insert(value);
}
Ok(Value::attrs(NixAttrs::from_map(map)))
}),
Builtin::new(
"mul",
&[false, false],

View file

@ -0,0 +1 @@
"AAbar"

View file

@ -0,0 +1,15 @@
with builtins;
let
fold = op: nul: list:
if list == []
then nul
else op (head list) (fold op nul (tail list));
concat =
fold (x: y: x + y) "";
asi = name: value : { inherit name value; };
list = [ ( asi "a" "A" ) ( asi "b" "B" ) ];
a = builtins.listToAttrs list;
b = builtins.listToAttrs ( list ++ list );
r = builtins.listToAttrs [ (asi "result" [ a b ]) ( asi "throw" (throw "this should not be thrown")) ];
x = builtins.listToAttrs [ (asi "foo" "bar") (asi "foo" "bla") ];
in concat (map (x: x.a) r.result) + x.foo