about summary refs log tree commit diff
path: root/tvix/eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src')
-rw-r--r--tvix/eval/src/io.rs23
-rw-r--r--tvix/eval/src/value/mod.rs3
2 files changed, 24 insertions, 2 deletions
diff --git a/tvix/eval/src/io.rs b/tvix/eval/src/io.rs
index 4e7404ef9c..d20912f21f 100644
--- a/tvix/eval/src/io.rs
+++ b/tvix/eval/src/io.rs
@@ -16,7 +16,7 @@
 //! how store paths are opened and so on.
 
 use smol_str::SmolStr;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
 use crate::errors::ErrorKind;
@@ -42,6 +42,15 @@ pub trait EvalIO {
     /// of its entries associated with their [`FileType`].
     fn read_dir(&self, path: PathBuf) -> Result<Vec<(SmolStr, FileType)>, ErrorKind>;
 
+    /// Import the given path. What this means depends on the
+    /// implementation, for example for a `std::io`-based
+    /// implementation this might be a no-op, while for a Tvix store
+    /// this might be a copy of the given files to the store.
+    ///
+    /// This is primarily used in the context of things like coercing
+    /// a local path to a string, or builtins like `path`.
+    fn import_path(&self, path: &Path) -> Result<PathBuf, ErrorKind>;
+
     /// Returns the root of the store directory, if such a thing
     /// exists in the evaluation context.
     fn store_dir(&self) -> Option<String> {
@@ -103,6 +112,12 @@ impl EvalIO for StdIO {
 
         Ok(result)
     }
+
+    // this is a no-op for `std::io`, as the user can already refer to
+    // the path directly
+    fn import_path(&self, path: &Path) -> Result<PathBuf, ErrorKind> {
+        Ok(path.to_path_buf())
+    }
 }
 
 /// Dummy implementation of [`EvalIO`], can be used in contexts where
@@ -127,4 +142,10 @@ impl EvalIO for DummyIO {
             "I/O methods are not implemented in DummyIO",
         ))
     }
+
+    fn import_path(&self, _: &Path) -> Result<PathBuf, ErrorKind> {
+        Err(ErrorKind::NotImplemented(
+            "I/O methods are not implemented in DummyIO",
+        ))
+    }
 }
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index 583d0c38e4..3e59c19c31 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -185,7 +185,8 @@ impl Value {
             // sequences without NUL bytes, whereas Tvix only allows valid
             // Unicode. See also b/189.
             (Value::Path(p), kind) if kind != CoercionKind::ThunksOnly => {
-                Ok(p.to_string_lossy().into_owned().into())
+                let imported = vm.io().import_path(p)?;
+                Ok(imported.to_string_lossy().into_owned().into())
             }
 
             // Attribute sets can be converted to strings if they either have an