provenant-cli 0.0.33

Rust-based ScanCode-compatible scanner for licenses, package metadata, SBOMs, and provenance data.
Documentation
// SPDX-FileCopyrightText: Provenant contributors
// SPDX-License-Identifier: Apache-2.0

use std::collections::HashMap;
use std::path::Path;

use crate::models::{FileInfo, FileType};

pub(crate) struct DirectoryTree {
    child_dirs: HashMap<String, Vec<String>>,
    dirs_deepest_first: Vec<String>,
}

impl DirectoryTree {
    pub(crate) fn build(files: &[FileInfo]) -> Self {
        let mut child_dirs: HashMap<String, Vec<String>> = HashMap::new();
        let mut dir_paths: Vec<String> = Vec::new();

        for entry in files {
            if entry.file_type == FileType::Directory {
                dir_paths.push(entry.path.clone());
            }
            if let Some(parent) = Path::new(&entry.path).parent().and_then(|p| p.to_str())
                && !parent.is_empty()
                && entry.file_type == FileType::Directory
            {
                child_dirs
                    .entry(parent.to_string())
                    .or_default()
                    .push(entry.path.clone());
            }
        }

        dir_paths.sort_by_key(|path| usize::MAX - Path::new(path).components().count());

        DirectoryTree {
            child_dirs,
            dirs_deepest_first: dir_paths,
        }
    }

    pub(crate) fn dirs_deepest_first(&self) -> &[String] {
        &self.dirs_deepest_first
    }

    pub(crate) fn child_dirs(&self, dir_path: &str) -> &[String] {
        self.child_dirs.get(dir_path).map_or(&[], |v| v)
    }
}