about summary refs log tree commit diff
path: root/tvix/eval/src/builtins/mod.rs
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2022-09-19T08·14+0200
committersterni <sternenseemann@systemli.org>2022-09-21T13·08+0000
commit0096939bf6edd9fd87cd555820c741b0da5508f2 (patch)
treec4abe50b9dcd764bec27f90f51bfc39a3ab807a4 /tvix/eval/src/builtins/mod.rs
parent489395448f0fbe268c6503018012992e1e6cfc22 (diff)
feat(tvix/eval): implement builtins.splitVersion r/4945
This was fairly easy, thanks to the work already done by Thomas Frank.
However, the implementation is suboptimal because we parse number parts
only to convert them back to strings afterwards. I've chosen to tackle
this problem in the future, since having an (inefficient) implementation
of splitVersion will be helpful for debugging the slight discrepancies
between C++ Nix and Tvix in the case of compareVersions.

Change-Id: Id6ed8eeb77663ff650c8c53ea952875b1fb7ea84
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6688
Autosubmit: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/builtins/mod.rs')
-rw-r--r--tvix/eval/src/builtins/mod.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs
index 1ea23d49e632..02457340dcd1 100644
--- a/tvix/eval/src/builtins/mod.rs
+++ b/tvix/eval/src/builtins/mod.rs
@@ -18,7 +18,7 @@ use crate::{
 
 use crate::arithmetic_op;
 
-use self::versions::VersionPartsIter;
+use self::versions::{VersionPart, VersionPartsIter};
 
 pub mod versions;
 
@@ -213,6 +213,21 @@ fn pure_builtins() -> Vec<Builtin> {
             let a = args.pop().unwrap();
             arithmetic_op!(a, b, *)
         }),
+        Builtin::new("splitVersion", &[true], |args, _| {
+            let s = args[0].to_str()?;
+            let s = VersionPartsIter::new(s.as_str());
+
+            let parts = s
+                .map(|s| {
+                    Value::String(match s {
+                        // TODO(sterni): we should avoid converting back and forth here
+                        VersionPart::Number(n) => format!("{n}").into(),
+                        VersionPart::Word(w) => w.into(),
+                    })
+                })
+                .collect::<Vec<Value>>();
+            Ok(Value::List(NixList::construct(parts.len(), parts)))
+        }),
         Builtin::new("sub", &[true, true], |mut args, _| {
             let b = args.pop().unwrap();
             let a = args.pop().unwrap();