feat(tvix/eval): implement Value::coerce_to_path()
This function is necessary for all builtins that expect some form of path as an argument. It is merely a wrapper around coerce_to_string that can shortcut if we already have a path. The absolute path check is done in the same way as in C++ Nix for compatibility, although it should probably be revised in the long term (think about Windows, for example). Since coercing to a path is not an operation possible in the language directly, this function can live in the builtins module as the only place it is required. Change-Id: I69ed5455c00d193fea88b8fa83e28907a761cab5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6574 Autosubmit: sterni <sternenseemann@systemli.org> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
parent
e834a2cbc4
commit
067f2b16f6
4 changed files with 48 additions and 1 deletions
|
@ -5,12 +5,14 @@
|
|||
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
path::PathBuf,
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
errors::ErrorKind,
|
||||
value::{Builtin, CoercionKind, NixAttrs, NixList, NixString, Value},
|
||||
vm::VM,
|
||||
};
|
||||
|
||||
use crate::arithmetic_op;
|
||||
|
@ -36,6 +38,30 @@ macro_rules! force {
|
|||
};
|
||||
}
|
||||
|
||||
/// Coerce a Nix Value to a plain path, e.g. in order to access the file it
|
||||
/// points to in an I/O builtin. This coercion can _never_ be performed in
|
||||
/// a Nix program directly (i.e. the trick `path: /. + path` to convert from
|
||||
/// a string to a path wouldn't hit this code), so the target file
|
||||
/// doesn't need to be realised or imported into the Nix store.
|
||||
pub fn coerce_value_to_path(v: &Value, vm: &mut VM) -> Result<PathBuf, ErrorKind> {
|
||||
force!(vm, v, value, {
|
||||
match value {
|
||||
Value::Thunk(t) => coerce_value_to_path(&t.value(), vm),
|
||||
Value::Path(p) => Ok(p.clone()),
|
||||
_ => value
|
||||
.coerce_to_string(CoercionKind::Weak, vm)
|
||||
.map(|s| PathBuf::from(s.as_str()))
|
||||
.and_then(|path| {
|
||||
if path.is_absolute() {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(ErrorKind::NotAnAbsolutePath(path))
|
||||
}
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Return all pure builtins, that is all builtins that do not rely on
|
||||
/// I/O outside of the VM and which can be used in any contexts (e.g.
|
||||
/// WASM).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue