summaryrefslogtreecommitdiffstats
path: root/src/fs.rs
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2025-07-07 15:14:12 +0000
committerSanto Cariotti <santo@dcariotti.me>2025-07-07 15:14:12 +0000
commit5fb45710f57f95eec527958400f8ec0a049c5fe4 (patch)
tree5a698f60ceec8954fcc5b2e19cbc7b9beea06a43 /src/fs.rs
parent2ef7371f7a4eefe7478cad43cb4922efaa12876a (diff)
Make tree for folders
Diffstat (limited to 'src/fs.rs')
-rw-r--r--src/fs.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/fs.rs b/src/fs.rs
new file mode 100644
index 0000000..cb8ce66
--- /dev/null
+++ b/src/fs.rs
@@ -0,0 +1,53 @@
+//! Provides the module used for filesystem operations made by this library.
+
+use std::path::Path;
+
+use crate::{hasher::Hasher, node::Node};
+
+/// Reads the entire content of a file into a `Vec<u8>`.
+///
+/// If the file cannot be read, an error message is printed to stderr, and the program exits.
+///
+/// `path` is a reference to a `String` representing the path to the file.
+fn read_file_content(path: &String) -> Vec<u8> {
+ match std::fs::read(path) {
+ Ok(contents) => contents,
+ Err(e) => {
+ eprintln!("Failed to read file '{}': {}", path, e);
+ std::process::exit(1);
+ }
+ }
+}
+
+/// Recursively hashes the contents of files and directories.
+///
+/// This function iterates through a list of filenames. For each file, it reads its content,
+/// hashes it using the provided `Hasher`, and creates a leaf `Node`. If an entry is a directory,
+/// it recursively calls itself to hash the directory's contents and extends the current
+/// list of nodes with the results.
+pub fn hash_dir<H>(hasher: H, filenames: Vec<String>) -> Vec<Node>
+where
+ H: Hasher + 'static + std::marker::Sync + Clone,
+{
+ let mut nodes: Vec<Node> = vec![];
+ for filename in &filenames {
+ let file = Path::new(filename);
+ if file.is_file() {
+ let hash = hasher.hash(read_file_content(filename).as_slice());
+
+ nodes.push(Node::new_leaf(hash));
+ } else if file.is_dir() {
+ let mut filenames_in_dir: Vec<String> = file
+ .read_dir()
+ .unwrap()
+ .map(|entry| String::from(entry.unwrap().path().to_str().unwrap()))
+ .collect();
+
+ filenames_in_dir.sort();
+
+ nodes.extend(hash_dir(hasher.clone(), filenames_in_dir));
+ }
+ }
+
+ nodes
+}