about summary refs log tree commit diff
path: root/tvix/serde
diff options
context:
space:
mode:
authorEvgeny Zemtsov <eze@resoptima.com>2023-06-22T15·57+0200
committerezemtsov <eugene.zemtsov@gmail.com>2023-06-22T20·19+0000
commitc8fcdca4eb09709966ea25883cbe91f34c038236 (patch)
tree52dfa7ab1bbc8f9afdb1e94c130fe6cd70c4bb35 /tvix/serde
parent8cdad7d45c6c58f0b93f0ca5b4779e31bd845bb9 (diff)
feat(tvix/eval): allow extending builtins outside of tvix_eval r/6344
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
Diffstat (limited to 'tvix/serde')
-rw-r--r--tvix/serde/Cargo.toml3
-rw-r--r--tvix/serde/src/de_tests.rs34
2 files changed, 37 insertions, 0 deletions
diff --git a/tvix/serde/Cargo.toml b/tvix/serde/Cargo.toml
index 8ffc11a4eb6e..774214eab667 100644
--- a/tvix/serde/Cargo.toml
+++ b/tvix/serde/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2021"
 [dependencies]
 tvix-eval = { path = "../eval" }
 serde = { version = "1.0", features = ["derive"] }
+
+[dev-dependencies]
+genawaiter = { version = "0.99.1", default_features = false }
\ No newline at end of file
diff --git a/tvix/serde/src/de_tests.rs b/tvix/serde/src/de_tests.rs
index 50a078cc0998..a77a59f2b5cd 100644
--- a/tvix/serde/src/de_tests.rs
+++ b/tvix/serde/src/de_tests.rs
@@ -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");
+}