diff --git a/.gitignore b/.gitignore index aec297f..56512f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target prod +tarpaulin-report.html diff --git a/Cargo.lock b/Cargo.lock index 3863fda..3ce1f9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,7 @@ dependencies = [ "derive_builder", "mime", "mime_guess", + "serde", "sha2", "walkdir", ] @@ -186,6 +187,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "serde" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" + [[package]] name = "sha2" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 73f2cea..c16f6b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ sha2 = "0.9.3" derive_builder = "0.10.0" data-encoding = "2.3.2" walkdir = "2" +serde = "1.0.125" diff --git a/src/hash.rs b/src/hash.rs index 49fe8f5..d81c2b5 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -5,7 +5,6 @@ * License. */ -use std::collections::HashMap; use std::io::Error; use std::path::Path; use std::{fs, path::PathBuf}; @@ -13,6 +12,8 @@ use std::{fs, path::PathBuf}; use derive_builder::Builder; use walkdir::WalkDir; +use crate::map::Files; + #[derive(Debug, Clone, Builder)] pub struct Buster { // source directory @@ -52,8 +53,8 @@ impl Buster { // use [hash] when when they aren't // // doesn't process files for which mime is not resolved - pub fn try_hash(&self) -> Result, Error> { - let mut file_map: HashMap = HashMap::default(); + pub fn try_hash(&self) -> Result { + let mut file_map: Files = Files::default(); for entry in WalkDir::new(&self.source) .follow_links(self.follow_links) .into_iter() @@ -76,10 +77,12 @@ impl Buster { self.copy(path, &new_name); let (source, destination) = self.gen_map(path, &&new_name); - file_map.insert( - source.to_str().unwrap().into(), - destination.to_str().unwrap().into(), - ); + file_map + .add( + source.to_str().unwrap().into(), + destination.to_str().unwrap().into(), + ) + .unwrap(); } } } @@ -90,8 +93,8 @@ impl Buster { // panics when mimetypes are detected. This way you'll know which files are ignored // from processing - pub fn hash(&self) -> Result, Error> { - let mut file_map: HashMap = HashMap::default(); + pub fn hash(&self) -> Result { + let mut file_map: Files = Files::default(); for entry in WalkDir::new(&self.source) .follow_links(self.follow_links) @@ -118,10 +121,12 @@ impl Buster { ); self.copy(path, &new_name); let (source, destination) = self.gen_map(path, &&new_name); - file_map.insert( - source.to_str().unwrap().into(), - destination.to_str().unwrap().into(), - ); + file_map + .add( + source.to_str().unwrap().into(), + destination.to_str().unwrap().into(), + ) + .unwrap(); } } } @@ -205,9 +210,9 @@ mod tests { .unwrap(); config.init().unwrap(); - let mut map = config.hash().unwrap(); + let mut files = config.hash().unwrap(); - for (k, v) in map.drain() { + for (k, v) in files.map.drain() { let src = Path::new(&k); let dest = Path::new(&v); @@ -234,9 +239,9 @@ mod tests { .unwrap(); config.init().unwrap(); - let mut map = config.hash().unwrap(); + let mut files = config.try_hash().unwrap(); - for (k, v) in map.drain() { + for (k, v) in files.map.drain() { let src = Path::new(&k); let dest = Path::new(&v); diff --git a/src/lib.rs b/src/lib.rs index 8a8ee45..86b1d72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,4 +33,6 @@ //! ``` pub mod hash; +pub mod map; pub use hash::BusterBuilder; +pub use map::Files; diff --git a/src/map.rs b/src/map.rs new file mode 100644 index 0000000..c08b2bb --- /dev/null +++ b/src/map.rs @@ -0,0 +1,76 @@ +/* +* Copyright (C) 2021 Aravinth Manivannan +* +* Use of this source code is governed by the Apache 2.0 and/or the MIT +* License. +*/ + +use std::collections::HashMap; + +#[derive(Debug, Default, Clone)] +pub struct Files { + pub map: HashMap, + base_dir: String, +} + +impl Files { + pub fn get<'a>(&'a self, path: &'a str) -> Option<&'a String> { + self.map.get(path) + } + + pub fn add(&mut self, k: String, v: String) -> Result<(), &'static str> { + if self.map.contains_key(&k) { + Err("key exists") + } else { + self.map.insert(k, v); + Ok(()) + } + } +} + +#[cfg(test)] +mod tests { + use crate::hash::*; + + use super::*; + use std::path::Path; + + #[test] + fn get_works() { + let types = vec![ + mime::IMAGE_PNG, + mime::IMAGE_SVG, + mime::IMAGE_JPEG, + mime::IMAGE_GIF, + ]; + + let config = BusterBuilder::default() + .source("./dist") + .result("/tmp/prod2") + .mime_types(types) + .copy(true) + .follow_links(true) + .build() + .unwrap(); + + config.init().unwrap(); + let files = config.hash().unwrap(); + + assert!(file_exists("./dist/log-out.svg", &files)); + assert!(file_exists( + "./dist/a/b/c/d/s/d/svg/credit-card.svg", + &files + )); + + assert!(!file_exists("dist/log-out.svg", &files)); + assert!(!file_exists("dist/a/b/c/d/s/d/svg/credit-card.svg", &files)); + } + + fn file_exists(path: &str, files: &Files) -> bool { + if let Some(file) = files.get(path) { + Path::new(file).exists() + } else { + false + } + } +}