cfgmatic-paths 5.0.0

Cross-platform configuration path discovery following XDG and platform conventions
Documentation
//! Shared directory scanning utilities for [`PathFinder`](super::PathFinder).

use std::path::{Path, PathBuf};

use crate::Fs;
use crate::core::{ConfigCandidate, ConfigTier, FilePattern, PathStatus, SourceType};

/// Collect all configuration candidates matching a pattern inside a list of directories.
pub(super) fn collect_matching_candidates<F>(
    fs: &dyn Fs,
    dirs: &[PathBuf],
    tier: ConfigTier,
    pattern: &FilePattern,
    source_type: SourceType,
    path_status: F,
) -> Vec<ConfigCandidate>
where
    F: Fn(&Path) -> PathStatus,
{
    let mut candidates = Vec::new();

    for dir in dirs {
        if !fs.is_dir(dir) {
            if pattern.matches(dir) {
                candidates.push(ConfigCandidate::new(
                    dir.clone(),
                    path_status(dir),
                    tier,
                    source_type,
                ));
            }
            continue;
        }

        for entry in fs.read_dir(dir) {
            if pattern.matches(&entry) {
                candidates.push(ConfigCandidate::new(
                    entry.clone(),
                    path_status(&entry),
                    tier,
                    source_type,
                ));
            }
        }

        if let Some(filenames) = pattern.concrete_filenames() {
            for filename in filenames {
                let file_path = dir.join(&filename);
                if pattern.matches(&file_path) {
                    candidates.push(ConfigCandidate::new(
                        file_path.clone(),
                        path_status(&file_path),
                        tier,
                        source_type,
                    ));
                }
            }
        }
    }

    candidates
}