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:
parent
d0f571dcc0
commit
afdf1e0ed0
3 changed files with 33 additions and 0 deletions
|
@ -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],
|
||||
|
|
1
tvix/eval/src/tests/tvix_tests/eval-okay-listtoattrs.exp
Normal file
1
tvix/eval/src/tests/tvix_tests/eval-okay-listtoattrs.exp
Normal file
|
@ -0,0 +1 @@
|
|||
"AAbar"
|
15
tvix/eval/src/tests/tvix_tests/eval-okay-listtoattrs.nix
Normal file
15
tvix/eval/src/tests/tvix_tests/eval-okay-listtoattrs.nix
Normal 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
|
Loading…
Reference in a new issue