use std::{ collections::{hash_set::HashSet, BTreeMap}, io, path::Path, }; use cargo_toml_workspace::cargo_toml::AbstractFilesystem; use normalize_path::NormalizePath; /// This type stores the filesystem structure for the crate tarball /// extracted in memory and can be passed to /// `cargo_toml::Manifest::complete_from_abstract_filesystem`. #[derive(Debug, Default)] pub(super) struct Vfs(BTreeMap, HashSet>>); impl Vfs { /// * `path` - must be canonical, must not be empty. pub(super) fn add_path(&mut self, mut path: &Path) { while let Some(parent) = path.parent() { // Since path has parent, it must have a filename let filename = path.file_name().unwrap(); // `cargo_toml`'s implementation does the same thing. // https://docs.rs/cargo_toml/0.11.5/src/cargo_toml/afs.rs.html#24 let filename = filename.to_string_lossy(); self.0 .entry(parent.into()) .or_insert_with(|| HashSet::with_capacity(4)) .insert(filename.into()); path = parent; } } } impl AbstractFilesystem for Vfs { fn file_names_in(&self, rel_path: &str) -> io::Result>> { let rel_path = Path::new(rel_path).normalize(); Ok(self.0.get(&*rel_path).cloned().unwrap_or_default()) } }