From ef80d00b06f3d90e37a94d65ce8c56062b19a43a Mon Sep 17 00:00:00 2001 From: ThoFrank Date: Sat, 17 Sep 2022 09:23:50 +0200 Subject: feat(tvix_eval): Support builtins.compareVersions Added an Iterator over &str wich yields the VersionParts. Change-Id: I8043d423127446a173d01d290aab10de0c24a6fc Reviewed-on: https://cl.tvl.fyi/c/depot/+/6619 Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/builtins/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tvix/eval/src/builtins/mod.rs') diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 3f8b73f7d7..5b497cde7e 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -17,6 +17,10 @@ use crate::{ use crate::arithmetic_op; +use self::versions::VersionPartsIter; + +pub mod versions; + /// Helper macro to ensure that a value has been forced. The structure /// of this is a little cumbersome as there are different reference /// types depending on whether the value is inside a thunk or not. @@ -135,6 +139,25 @@ fn pure_builtins() -> Vec { Ok(Value::List(NixList::construct(output.len(), output))) }), + Builtin::new("compareVersions", 2, |mut args, vm| { + if let Value::Thunk(t) = &args[0] { + t.force(vm)?; + } + if let Value::Thunk(t) = &args[1] { + t.force(vm)?; + } + + let s1 = args.pop().unwrap().to_str()?; + let s1 = VersionPartsIter::new(s1.as_str()); + let s2 = args.pop().unwrap().to_str()?; + let s2 = VersionPartsIter::new(s2.as_str()); + + match s1.cmp(s2) { + std::cmp::Ordering::Less => Ok(Value::Integer(1)), + std::cmp::Ordering::Equal => Ok(Value::Integer(0)), + std::cmp::Ordering::Greater => Ok(Value::Integer(-1)), + } + }), Builtin::new("div", 2, |mut args, _| { let b = args.pop().unwrap(); let a = args.pop().unwrap(); -- cgit 1.4.1