diff options
author | Vincent Ambo <mail@tazj.in> | 2022-12-12T17·02+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-12-21T22·59+0000 |
commit | 4cb9ada0df188ae8484965749a30a2a699a3102e (patch) | |
tree | b017444c390d1d19e5c5f4ff715ada7d18612899 /tvix/eval/src/io.rs | |
parent | 51deadd983a7058348554672286736d67d999a67 (diff) |
refactor(tvix/eval): use `EvalIO::read_dir` for equivalent builtin r/5464
Change-Id: I6d782c07166f51587d2f1d06607823268debb5d5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7574 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/io.rs')
-rw-r--r-- | tvix/eval/src/io.rs | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/tvix/eval/src/io.rs b/tvix/eval/src/io.rs index 627eb848dcba..3215e5a7ddb7 100644 --- a/tvix/eval/src/io.rs +++ b/tvix/eval/src/io.rs @@ -15,10 +15,21 @@ //! In the context of Nix builds, callers also use this interface to determine //! how store paths are opened and so on. +use smol_str::SmolStr; use std::path::PathBuf; +use std::rc::Rc; use crate::errors::ErrorKind; +/// Types of files as represented by `builtins.readDir` in Nix. +#[derive(Debug)] +pub enum FileType { + Directory, + Regular, + Symlink, + Unknown, +} + /// Defines how filesystem interaction occurs inside of tvix-eval. pub trait EvalIO { /// Verify whether the file at the specified path exists. @@ -26,6 +37,10 @@ pub trait EvalIO { /// Read the file at the specified path to a string. fn read_to_string(&self, path: PathBuf) -> Result<String, ErrorKind>; + + /// Read the directory at the specified path and return the names + /// of its entries associated with their [`FileType`]. + fn read_dir(&self, path: PathBuf) -> Result<Vec<(SmolStr, FileType)>, ErrorKind>; } /// Implementation of [`EvalIO`] that simply uses the equivalent @@ -38,16 +53,50 @@ impl EvalIO for StdIO { fn path_exists(&self, path: PathBuf) -> Result<bool, ErrorKind> { path.try_exists().map_err(|e| ErrorKind::IO { path: Some(path), - error: std::rc::Rc::new(e), + error: Rc::new(e), }) } fn read_to_string(&self, path: PathBuf) -> Result<String, ErrorKind> { std::fs::read_to_string(&path).map_err(|e| ErrorKind::IO { path: Some(path), - error: std::rc::Rc::new(e), + error: Rc::new(e), }) } + + fn read_dir(&self, path: PathBuf) -> Result<Vec<(SmolStr, FileType)>, ErrorKind> { + let mut result = vec![]; + + let mk_err = |err| ErrorKind::IO { + path: Some(path.clone()), + error: Rc::new(err), + }; + + for entry in path.read_dir().map_err(mk_err)? { + let entry = entry.map_err(mk_err)?; + let file_type = entry + .metadata() + .map_err(|err| ErrorKind::IO { + path: Some(entry.path()), + error: Rc::new(err), + })? + .file_type(); + + let val = if file_type.is_dir() { + FileType::Directory + } else if file_type.is_file() { + FileType::Regular + } else if file_type.is_symlink() { + FileType::Symlink + } else { + FileType::Unknown + }; + + result.push((SmolStr::new(entry.file_name().to_string_lossy()), val)); + } + + Ok(result) + } } /// Dummy implementation of [`EvalIO`], can be used in contexts where @@ -66,4 +115,10 @@ impl EvalIO for DummyIO { "I/O methods are not implemented in DummyIO", )) } + + fn read_dir(&self, _: PathBuf) -> Result<Vec<(SmolStr, FileType)>, ErrorKind> { + Err(ErrorKind::NotImplemented( + "I/O methods are not implemented in DummyIO", + )) + } } |