feat(tvix/eval): builtins: implement parseDrvName

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>
This commit is contained in:
Adam Joseph 2022-10-09 12:46:21 -07:00
parent 32ac7d6c6d
commit 8111f2de1e

View file

@ -381,6 +381,31 @@ fn pure_builtins() -> Vec<Builtin> {
Ok(Value::attrs(NixAttrs::from_map(res))) 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| { Builtin::new("splitVersion", &[true], |args: Vec<Value>, _: &mut VM| {
let s = args[0].to_str()?; let s = args[0].to_str()?;
let s = VersionPartsIter::new(s.as_str()); let s = VersionPartsIter::new(s.as_str());