about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-12-12T14·19+0300
committertazjin <tazjin@tvl.su>2022-12-21T22·37+0000
commit25fc6b7c25d75075461e7976b27b81ba6a8140fe (patch)
tree591e4bbec276ead8cbce0c847e79449733ca7ad1
parentbf286a54bc2ac5eeb78c3d5c5ae66e9af24d74d4 (diff)
feat(tvix/eval): introduce initial EvalIO trait r/5458
This trait is going to be used to abstract filesystem interactions in
Tvix.

For now, it only contains a `read_to_string` method that closely
mirrors `std::fs::read_to_string`.

As a first step, to see how this works in practice, we will thread
through only this function to the various relevant parts.

Two implementations are provided in tvix-eval itself: A dummy
implementation (which just returns ErrorKind::NotImplemented for all
operations), and a std implementation which delegates to `std`
functions.

Change-Id: Ied3e3bf4bd0e874dd84e166190e3873a0f923ddb
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7565
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
-rw-r--r--tvix/eval/src/io.rs52
-rw-r--r--tvix/eval/src/lib.rs1
2 files changed, 53 insertions, 0 deletions
diff --git a/tvix/eval/src/io.rs b/tvix/eval/src/io.rs
new file mode 100644
index 0000000000..8003746c48
--- /dev/null
+++ b/tvix/eval/src/io.rs
@@ -0,0 +1,52 @@
+//! Interface for injecting I/O-related functionality into tvix-eval.
+//!
+//! The Nix language contains several builtins (e.g. `builtins.readDir`), as
+//! well as language feature (e.g. string-"coercion" of paths) that interact
+//! with the filesystem.
+//!
+//! The language evaluator implemented by this crate does not depend on any
+//! particular filesystem interaction model. Instead, this module provides a
+//! trait that can be implemented by tvix-eval callers to provide the
+//! functionality they desire.
+//!
+//! In theory this can be used to implement "mocked" filesystem interactions, or
+//! interaction with remote filesystems, etc.
+//!
+//! In the context of Nix builds, callers also use this interface to determine
+//! how store paths are opened and so on.
+
+use std::path::PathBuf;
+
+use crate::errors::ErrorKind;
+
+/// Defines how filesystem interaction occurs inside of tvix-eval.
+pub trait EvalIO {
+    /// Read the file at the specified path to a string.
+    fn read_to_string(&self, path: PathBuf) -> Result<String, ErrorKind>;
+}
+
+/// Implementation of [`EvalIO`] that simply uses the equivalent
+/// standard library functions, i.e. does local file-IO.
+struct StdIO;
+
+impl EvalIO for StdIO {
+    fn read_to_string(&self, path: PathBuf) -> Result<String, ErrorKind> {
+        let path: PathBuf = path.into();
+        std::fs::read_to_string(&path).map_err(|e| ErrorKind::IO {
+            path: Some(path),
+            error: std::rc::Rc::new(e),
+        })
+    }
+}
+
+/// Dummy implementation of [`EvalIO`], can be used in contexts where
+/// IO is not available but code should "pretend" that it is.
+struct DummyIO;
+
+impl EvalIO for DummyIO {
+    fn read_to_string(&self, _: PathBuf) -> Result<String, ErrorKind> {
+        Err(ErrorKind::NotImplemented(
+            "I/O methods are not implemented in DummyIO",
+        ))
+    }
+}
diff --git a/tvix/eval/src/lib.rs b/tvix/eval/src/lib.rs
index 4a5ae6f3e8..c9a6ac103e 100644
--- a/tvix/eval/src/lib.rs
+++ b/tvix/eval/src/lib.rs
@@ -16,6 +16,7 @@ mod builtins;
 mod chunk;
 mod compiler;
 mod errors;
+mod io;
 pub mod observer;
 mod opcode;
 mod pretty_ast;