feat(tvix/eval): allow extending builtins outside of tvix_eval

The change allows applications that use tvix_serde for parsing
nix-based configuration to extend the language with domain-specific
set of features.

Change-Id: Ia86612308a167c456ecf03e93fe0fbae55b876a6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8848
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Evgeny Zemtsov 2023-06-22 17:57:50 +02:00 committed by ezemtsov
parent 8cdad7d45c
commit c8fcdca4eb
9 changed files with 55 additions and 9 deletions

View file

@ -1,5 +1,6 @@
use serde::Deserialize;
use std::collections::HashMap;
use tvix_eval::builtin_macros::builtins;
use crate::de::{from_str, from_str_with_config};
@ -209,3 +210,36 @@ fn deserialize_with_config() {
assert_eq!(result, "ok");
}
#[builtins]
mod test_builtins {
use genawaiter::rc::Gen;
use tvix_eval::generators::GenCo;
use tvix_eval::{ErrorKind, NixString, Value};
#[builtin("prependHello")]
pub async fn builtin_prepend_hello(co: GenCo, x: Value) -> Result<Value, ErrorKind> {
match x {
Value::String(s) => {
let new_string = NixString::from(format!("hello {}", s.as_str()));
Ok(Value::String(new_string))
}
_ => Err(ErrorKind::TypeError {
expected: "string",
actual: "not string",
}),
}
}
}
#[test]
fn deserialize_with_extra_builtin() {
let code = "builtins.prependHello \"world\"";
let result: String = from_str_with_config(code, |eval| {
eval.builtins.append(&mut test_builtins::builtins());
})
.expect("should deserialize");
assert_eq!(result, "hello world");
}