From 493adb4688d445d52e1227eb03dce31d274b3741 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 19 Oct 2024 16:15:23 -0400 Subject: [PATCH] Switch to iterative instead of recursive. --- src/command/build/runner.rs | 16 +++++++-- src/command/build/walk_fs.rs | 66 +++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/command/build/runner.rs b/src/command/build/runner.rs index a36c9af..b9fe1b7 100644 --- a/src/command/build/runner.rs +++ b/src/command/build/runner.rs @@ -5,6 +5,7 @@ use std::sync::Mutex; use super::stylesheet::Stylesheet; use super::walk_fs::walk_fs; +use super::walk_fs::WalkAction; use crate::cli::parameters::BuildArgs; use crate::command::build::render::SiteRenderer; use crate::config::Config; @@ -61,12 +62,21 @@ async fn get_output_directory(config: &Config) -> Result { Ok(output_directory) } -async fn filter_to_post_directories(entry: &DirEntry) -> Result { - Ok(true) +async fn filter_to_highest_folders_containing_org_files( + entry: &DirEntry, +) -> Result { + let file_type = entry.file_type().await?; + let mut entries = tokio::fs::read_dir(entry.path()).await?; + + todo!() } async fn get_post_directories(config: &Config) -> Result, CustomError> { - walk_fs(config.get_posts_directory(), filter_to_post_directories).await?; + walk_fs( + config.get_posts_directory(), + filter_to_highest_folders_containing_org_files, + ) + .await?; let mut ret = Vec::new(); if !config.get_posts_directory().exists() { diff --git a/src/command/build/walk_fs.rs b/src/command/build/walk_fs.rs index 0361a70..cf20661 100644 --- a/src/command/build/walk_fs.rs +++ b/src/command/build/walk_fs.rs @@ -1,35 +1,53 @@ -use std::future::Future; +use std::collections::VecDeque; use std::ops::AsyncFn; -use std::path::Path; +use std::path::PathBuf; -use futures::future::BoxFuture; -use futures::FutureExt; use tokio::fs::DirEntry; use crate::error::CustomError; -pub(crate) fn walk_fs<'p, P: AsRef + std::marker::Send + 'p>( +pub(crate) async fn walk_fs< + P: Into, + F: AsyncFn(&DirEntry) -> Result, +>( root: P, - predicate: impl AsyncFn(&DirEntry) -> Result - + std::marker::Send - + 'p - + std::marker::Copy, -) -> BoxFuture<'p, Result, CustomError>> { - async move { - let mut ret = Vec::new(); - let mut entries = tokio::fs::read_dir(root).await?; + filter: F, +) -> Result, CustomError> { + let mut ret = Vec::new(); + let mut backlog = VecDeque::new(); + backlog.push_back(root.into()); + while let Some(p) = backlog.pop_front() { + let mut entries = tokio::fs::read_dir(p).await?; while let Some(entry) = entries.next_entry().await? { - let file_type = entry.file_type().await?; - if file_type.is_dir() { - let child_entries = walk_fs(entry.path(), predicate).await?; - ret.extend(child_entries); - } - if predicate(&entry).await? { - ret.push(entry); - } + let action = filter(&entry).await?; + match action { + WalkAction::HaltAndCapture => { + ret.push(entry); + } + WalkAction::Halt => {} + WalkAction::RecurseAndCapture => { + backlog.push_back(entry.path()); + ret.push(entry); + } + WalkAction::Recurse => { + backlog.push_back(entry.path()); + } + }; } - - Ok(ret) } - .boxed() + Ok(ret) +} + +pub(crate) enum WalkAction { + /// Do not walk down this path but add it to the return list. + HaltAndCapture, + + /// Do not walk down this path and do not add it to the return list. + Halt, + + /// Walk down this path and add it to the return list. + RecurseAndCapture, + + /// Walk down this path but do not add it to the return list. + Recurse, }