diff options
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 15 | ||||
-rw-r--r-- | tvix/eval/src/value/list.rs | 4 |
2 files changed, 18 insertions, 1 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index ce048e22be0d..11e0dc8d9fa7 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -10,7 +10,7 @@ use std::{ use crate::{ errors::ErrorKind, - value::{Builtin, NixAttrs, NixString, Value}, + value::{Builtin, NixAttrs, NixList, NixString, Value}, }; fn pure_builtins() -> Vec<Builtin> { @@ -20,6 +20,19 @@ fn pure_builtins() -> Vec<Builtin> { ErrorKind::Abort(args.pop().unwrap().to_string()?.as_str().to_owned()).into(), ); }), + Builtin::new("catAttrs", 2, |mut args| { + let list = args.pop().unwrap().to_list()?; + let key = args.pop().unwrap().to_string()?; + let mut output = vec![]; + + for set in list.into_iter() { + if let Some(value) = set.to_attrs()?.select(key.as_str()) { + output.push(value.clone()); + } + } + + Ok(Value::List(NixList::construct(output.len(), output))) + }), Builtin::new("isAttrs", 1, |args| { Ok(Value::Bool(matches!(args[0], Value::Attrs(_)))) }), diff --git a/tvix/eval/src/value/list.rs b/tvix/eval/src/value/list.rs index 31f223fce599..77776c4dce62 100644 --- a/tvix/eval/src/value/list.rs +++ b/tvix/eval/src/value/list.rs @@ -38,4 +38,8 @@ impl NixList { NixList(stack_slice) } + + pub fn into_iter(self) -> std::vec::IntoIter<Value> { + self.0.into_iter() + } } |