feat(tvix/eval): Implement builtins.mapAttrs

I played around a little bit with doing this in-place, but ended up
going with this perhaps slightly clone-heavy approach for now because
ideally most clones on Value are cheap - but later we should benchmark
alternate approaches that get to reuse allocations better if necessary
or possible.

Change-Id: If998eb2056cedefdf2fb480b0568ac8329ccfc44
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7068
Autosubmit: grfn <grfn@gws.fyi>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Griffin Smith 2022-10-23 12:28:23 -04:00 committed by grfn
parent 8497b83569
commit 7b3bda9e08
4 changed files with 23 additions and 0 deletions

View file

@ -435,6 +435,19 @@ fn pure_builtins() -> Vec<Builtin> {
.map(|list| Value::List(NixList::from(list)))
.map_err(Into::into)
}),
Builtin::new(
"mapAttrs",
&[true, true],
|args: Vec<Value>, vm: &mut VM| {
let attrs = args[1].to_attrs()?;
let mut res = BTreeMap::new();
for (key, value) in attrs.as_ref() {
let value = vm.call_with(&args[0], [key.clone().into(), value.clone()])?;
res.insert(key.clone(), value);
}
Ok(Value::attrs(NixAttrs::from_map(res)))
},
),
Builtin::new(
"match",
&[true, true],

View file

@ -517,3 +517,13 @@ impl<'a> Iterator for Keys<'a> {
}
}
}
impl<'a> IntoIterator for &'a NixAttrs {
type Item = (&'a NixString, &'a Value);
type IntoIter = Iter<KeyValue<'a>>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}