From 2ffce0347e69ec1576db9cf1aff58ad81be7c243 Mon Sep 17 00:00:00 2001 From: Adam French Date: Mon, 2 Mar 2026 21:54:37 +0000 Subject: [PATCH] add utils for copying files and retrieving session info --- src/utils.rs | 63 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 42d8b46..e483532 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,23 +2,62 @@ use std::fs; use std::io; use std::path::Path; -pub fn copy_files(files: Vec<&Path>, dest_dir: &Path) -> Result<(), io::Error> { - for file in files { - // Get the relative path components - let dest_path = dest_dir.join(file); +use crate::SESSION_PATH; +use crate::TOUR_DIR; - // Create parent directories if they don't exist - if let Some(parent) = dest_path.parent() { +/// Copies a file or directory into dest_dir, preserving relative path structure. +/// e.g. `src/main.rs` → `dest_dir/src/main.rs` +pub fn copy_path(src: &Path, dest_dir: &Path) -> Result<(), io::Error> { + let relative_src = if src.is_absolute() { + let cwd = std::env::current_dir()?; + src.strip_prefix(&cwd).unwrap_or(src).to_path_buf() + } else { + src.to_path_buf() + }; + + if src.is_dir() { + let dest = dest_dir.join(&relative_src); + fs::create_dir_all(&dest)?; + for entry in fs::read_dir(src)? { + let entry = entry?; + copy_path(&entry.path(), dest_dir)?; + } + } else { + let dest = dest_dir.join(&relative_src); + if let Some(parent) = dest.parent() { fs::create_dir_all(parent)?; } - - // Copy the file - fs::copy(file, dest_path)?; + fs::copy(src, &dest)?; } Ok(()) } -pub fn session_step(session_file: &Path) -> Result> { - // Read ./.tour/session to find what step user is currently looking at - Ok((0)) +pub fn is_descendant_of_current_dir(file: &Path) -> Result { + is_file_in_dir(file, &std::env::current_dir()?) +} + +pub fn is_file_in_dir(file: &Path, dir: &Path) -> Result { + let file_canon = file.canonicalize()?; + let dir_canon = dir.canonicalize()?; + Ok(file_canon.starts_with(&dir_canon)) +} + +pub fn get_session_step() -> Result> { + let session = fs::read_to_string(SESSION_PATH)?; + let step = session + .split("STEP=") + .nth(1) + .ok_or("no STEP in session")? + .trim() + .parse::()?; + Ok(step) +} + +pub fn get_tour_step() -> Result> { + let steps_dir = Path::new(TOUR_DIR).join("steps"); + let count = fs::read_dir(&steps_dir)? + .filter_map(|e| e.ok()) + .filter(|e| e.path().is_dir()) + .count() as u32; + Ok(count) }