Switch to iterative instead of recursive.

This commit is contained in:
Tom Alexander 2024-10-19 16:15:23 -04:00
parent b6cc7a70b7
commit 493adb4688
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 55 additions and 27 deletions

View File

@ -5,6 +5,7 @@ use std::sync::Mutex;
use super::stylesheet::Stylesheet; use super::stylesheet::Stylesheet;
use super::walk_fs::walk_fs; use super::walk_fs::walk_fs;
use super::walk_fs::WalkAction;
use crate::cli::parameters::BuildArgs; use crate::cli::parameters::BuildArgs;
use crate::command::build::render::SiteRenderer; use crate::command::build::render::SiteRenderer;
use crate::config::Config; use crate::config::Config;
@ -61,12 +62,21 @@ async fn get_output_directory(config: &Config) -> Result<PathBuf, CustomError> {
Ok(output_directory) Ok(output_directory)
} }
async fn filter_to_post_directories(entry: &DirEntry) -> Result<bool, CustomError> { async fn filter_to_highest_folders_containing_org_files(
Ok(true) entry: &DirEntry,
) -> Result<WalkAction, CustomError> {
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<Vec<PathBuf>, CustomError> { async fn get_post_directories(config: &Config) -> Result<Vec<PathBuf>, 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(); let mut ret = Vec::new();
if !config.get_posts_directory().exists() { if !config.get_posts_directory().exists() {

View File

@ -1,35 +1,53 @@
use std::future::Future; use std::collections::VecDeque;
use std::ops::AsyncFn; use std::ops::AsyncFn;
use std::path::Path; use std::path::PathBuf;
use futures::future::BoxFuture;
use futures::FutureExt;
use tokio::fs::DirEntry; use tokio::fs::DirEntry;
use crate::error::CustomError; use crate::error::CustomError;
pub(crate) fn walk_fs<'p, P: AsRef<Path> + std::marker::Send + 'p>( pub(crate) async fn walk_fs<
P: Into<PathBuf>,
F: AsyncFn(&DirEntry) -> Result<WalkAction, CustomError>,
>(
root: P, root: P,
predicate: impl AsyncFn(&DirEntry) -> Result<bool, CustomError> filter: F,
+ std::marker::Send ) -> Result<Vec<DirEntry>, CustomError> {
+ 'p let mut ret = Vec::new();
+ std::marker::Copy, let mut backlog = VecDeque::new();
) -> BoxFuture<'p, Result<Vec<DirEntry>, CustomError>> { backlog.push_back(root.into());
async move { while let Some(p) = backlog.pop_front() {
let mut ret = Vec::new(); let mut entries = tokio::fs::read_dir(p).await?;
let mut entries = tokio::fs::read_dir(root).await?;
while let Some(entry) = entries.next_entry().await? { while let Some(entry) = entries.next_entry().await? {
let file_type = entry.file_type().await?; let action = filter(&entry).await?;
if file_type.is_dir() { match action {
let child_entries = walk_fs(entry.path(), predicate).await?; WalkAction::HaltAndCapture => {
ret.extend(child_entries); ret.push(entry);
} }
if predicate(&entry).await? { WalkAction::Halt => {}
ret.push(entry); 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,
} }