diff --git a/src/utils.rs b/src/utils.rs index 4177451234..95642d1d7a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -70,3 +70,129 @@ impl> Div for &RelativePath { RelativePath::new(result) } } + + +#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] +pub struct Res { + pub loc: PathBuf, + pub at: usize, +} + +impl Res {} + +pub struct FileStructure { + root: PathBuf, + pub resources: Vec, +} + +impl FileStructure { + pub fn new() -> FileStructure { + FileStructure { + root: PathBuf::new(), + resources: Vec::::new(), + } + } + + pub fn set_root(&mut self, path: &Path) { + self.root = path.to_path_buf(); + } + + pub fn paths_applying_with(&mut self, to: F) -> Vec<(PathBuf, PathBuf)> + where + F: Fn((PathBuf, usize)) -> (PathBuf, PathBuf), + { + self.resources + .iter() + .map(|f| (PathBuf::from(&f.loc), f.at)) + .map(|f| to(f)) + .collect() + } + + pub fn walk_decorate(&mut self, start_path: &Path) { + self.set_root(&dunce::canonicalize(start_path).unwrap()); + self.resources = Vec::::new(); + self.build(start_path, 0); + self.resources.sort(); + } + + fn build(&mut self, src: &'a Path, lvl: usize) { + let source = dunce::canonicalize(src).unwrap(); + + if source.is_dir() { + for entry in std::fs::read_dir(&source).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + + if path.is_dir() { + self.build(&path, lvl + 1); + } + + self.resources.push(Res { + loc: path.to_path_buf(), + at: lvl, + }); + } + } else { + self.resources.push(Res { + loc: source, + at: lvl, + }); + } + } +} + +#[cfg(test)] +mod tests { + + use super::{FileStructure, Res}; + use std::path::PathBuf; + + fn fixtures() -> PathBuf { + let mut sdx = PathBuf::new(); + sdx.push("tests"); + sdx.push("fixtures"); + sdx.push("formats"); + dunce::canonicalize(sdx).unwrap() + } + + #[test] + fn prepares_and_decorates_source_files_for_copying() { + let mut res = FileStructure::new(); + res.walk_decorate(fixtures().as_path()); + + assert_eq!( + res.resources, + vec![ + Res { + loc: fixtures().join("appveyor.yml"), + at: 0 + }, + Res { + loc: fixtures().join("caco3_plastics.csv"), + at: 0 + }, + Res { + loc: fixtures().join("cargo_sample.toml"), + at: 0 + }, + Res { + loc: fixtures().join("jonathan.xml"), + at: 0 + }, + Res { + loc: fixtures().join("sample.ini"), + at: 0 + }, + Res { + loc: fixtures().join("sgml_description.json"), + at: 0 + }, + Res { + loc: fixtures().join("utf16.ini"), + at: 0 + } + ] + ); + } +} +