mcserver 0.3.2

Minecraft Multiplexer
use std::{
    io::IsTerminal,
    path::{Path, PathBuf},
};

use tokio::fs;

use miette::{Context, IntoDiagnostic};

use crate::{consts::METADATA_DIRECTORY, core::display_path, stderr_log};

pub async fn read(root_dir: &Path) -> miette::Result<Vec<PathBuf>> {
    let mut servers = vec![];
    let mut paths = vec![root_dir.to_owned()];

    while let Some(path) = paths.iter().next_back() {
        let mut entries = fs::read_dir(path)
            .await
            .into_diagnostic()
            .wrap_err_with(|| {
                format!("Failed to read entries from directory {}", path.display())
            })?;

        let mut path_additions: Vec<PathBuf> = vec![];

        while let Some(entry) = entries
            .next_entry()
            .await
            .into_diagnostic()
            .wrap_err("Bad dir entry")?
        {
            let entry_path = entry.path();

            if !entry_path.is_dir() {
                continue;
            }

            stderr_log!("Entry path: {entry_path:?}");

            if fs::try_exists(entry_path.join(METADATA_DIRECTORY))
                .await
                .into_diagnostic()
                .wrap_err("Failed to check if directory exists")?
            {
                servers.push(
                    entry_path
                        .strip_prefix(root_dir)
                        .into_diagnostic()
                        .wrap_err_with(|| {
                            format!(
                                "Failed to strip `{}` from `{}`",
                                display_path(root_dir),
                                display_path(&entry_path)
                            )
                        })?
                        .to_path_buf(),
                );
            } else {
                path_additions.push(path.join(entry_path));
            }
        }

        paths.pop();
        paths.extend(path_additions);
    }

    Ok(servers)
}