about summary refs log tree commit diff
path: root/tvix/eval/src/builtins/mod.rs
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2022-10-09T19·46-0700
committerAdam Joseph <adam@westernsemico.com>2022-10-12T09·50+0000
commit8111f2de1e324cd08405a89f4d6a9a61f6621078 (patch)
tree7f6b085f8ccf8d124694cd3b85093b8edb59650d /tvix/eval/src/builtins/mod.rs
parent32ac7d6c6d06b5191fcc828b762b247b0e27dfda (diff)
feat(tvix/eval): builtins: implement parseDrvName r/5114
This commit passes nix_eval_okay_src_tests_nix_tests_eval_okay_versions_nix.

See also: https://github.com/NixOS/nix/pull/7149

Signed-off-by: Adam Joseph <adam@westernsemico.com>
Change-Id: I24605c2a0cd0da434f37f6c518f20693bfa1b799
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6913
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Diffstat (limited to 'tvix/eval/src/builtins/mod.rs')
-rw-r--r--tvix/eval/src/builtins/mod.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs
index 05c5eceeffda..a3aaf33bf4af 100644
--- a/tvix/eval/src/builtins/mod.rs
+++ b/tvix/eval/src/builtins/mod.rs
@@ -381,6 +381,31 @@ fn pure_builtins() -> Vec<Builtin> {
                 Ok(Value::attrs(NixAttrs::from_map(res)))
             },
         ),
+        Builtin::new("parseDrvName", &[true], |args: Vec<Value>, vm: &mut VM| {
+            // This replicates cppnix's (mis?)handling of codepoints
+            // above U+007f following 0x2d ('-')
+            let s = args[0].coerce_to_string(CoercionKind::Weak, vm)?;
+            let slice: &[u8] = s.as_str().as_ref();
+            let (name, dash_and_version) = slice.split_at(
+                slice
+                    .windows(2)
+                    .enumerate()
+                    .find_map(|x| match x {
+                        (idx, [b'-', c1]) if !c1.is_ascii_alphabetic() => Some(idx),
+                        _ => None,
+                    })
+                    .unwrap_or(slice.len()),
+            );
+            let version = dash_and_version
+                .split_first()
+                .map(|x| core::str::from_utf8(x.1))
+                .unwrap_or(Ok(""))?
+                .into();
+            Ok(Value::attrs(NixAttrs::from_map(BTreeMap::from([
+                (NixString::NAME, core::str::from_utf8(name)?.into()),
+                ("version".into(), version),
+            ]))))
+        }),
         Builtin::new("splitVersion", &[true], |args: Vec<Value>, _: &mut VM| {
             let s = args[0].to_str()?;
             let s = VersionPartsIter::new(s.as_str());