1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
// Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Module describing runtime compoenet for fetching modified filenames
//!
//! Add the following tou your program to load the filemap during compiletime:
//!
//! ```no_run
//! use cache_buster::Files;
//! use cache_buster::CACHE_BUSTER_DATA_FILE;
//!
//! let files = Files::new(CACHE_BUSTER_DATA_FILE);
//! ```
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
/// Filemap struct
///
/// maps original names to generated names
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct Files {
/// filemap<original-path, modified-path>
map: HashMap<String, String>,
base_dir: String,
}
impl Files {
/// Load filemap in main program. Should be called from main program
pub fn new(map: &str) -> Self {
let res: Files = serde_json::from_str(map).unwrap();
res
}
/// Get relative file path
///
/// If the modified filename path is `./prod/test.randomhash.svg`, it will
/// output `/test.randomhash.svg`. For full path, see [get_full_path][Self::get_full_path].
pub fn get(&self, path: impl AsRef<str>) -> Option<&str> {
if let Some(path) = self.map.get(path.as_ref()) {
Some(&path[self.base_dir.len()..])
// Some(&path)
} else {
None
}
}
/// Get file path
///
/// If the modified filename path is `./prod/test.randomhash.svg`, it will
/// output `/prod/test.randomhash.svg`. For relative path, see [get][Self::get].
pub fn get_full_path(&self, path: impl AsRef<str>) -> Option<&String> {
self.map.get(path.as_ref())
}
}
#[cfg(test)]
mod tests {
use std::fs;
use crate::processor::tests::{cleanup, delete_file, runner as processor_runner};
use crate::processor::*;
use crate::CACHE_BUSTER_DATA_FILE;
use super::*;
use std::path::Path;
fn get_full_path_works() {
delete_file();
let types = vec![
mime::IMAGE_PNG,
mime::IMAGE_SVG,
mime::IMAGE_JPEG,
mime::IMAGE_GIF,
];
let config = BusterBuilder::default()
.source("./dist")
.result("/tmp/prodsd2")
.mime_types(types)
.follow_links(true)
.build()
.unwrap();
config.process().unwrap();
let map = fs::read_to_string(CACHE_BUSTER_DATA_FILE).unwrap();
let files = Files::new(&map);
assert!(get_full_path_runner("./dist/log-out.svg", &files));
assert!(get_full_path_runner(
"./dist/a/b/c/d/s/d/svg/credit-card.svg",
&files
));
assert!(!get_full_path_runner("dist/log-out.svg", &files));
assert!(!get_full_path_runner(
"dist/a/b/c/d/s/d/svg/credit-card.svg",
&files
));
cleanup(&config);
}
fn get_full_path_runner(path: &str, files: &Files) -> bool {
if let Some(file) = files.get_full_path(path) {
Path::new(file).exists()
} else {
false
}
}
fn get_works() {
delete_file();
let types = vec![
mime::IMAGE_PNG,
mime::IMAGE_SVG,
mime::IMAGE_JPEG,
mime::IMAGE_GIF,
];
let config = BusterBuilder::default()
.source("./dist")
.result("/tmp/prod5")
.mime_types(types)
.follow_links(true)
.build()
.unwrap();
config.process().unwrap();
let map = fs::read_to_string(CACHE_BUSTER_DATA_FILE).unwrap();
let files = Files::new(&map);
assert!(get_runner("./dist/log-out.svg", &files));
assert!(get_runner("./dist/a/b/c/d/s/d/svg/credit-card.svg", &files));
assert!(!get_runner("dist/log-out.svg", &files));
assert!(!get_runner("dist/a/b/c/d/s/d/svg/credit-card.svg", &files));
cleanup(&config);
}
fn get_runner(path: &str, files: &Files) -> bool {
if let Some(file) = files.get(path) {
let path = Path::new(&files.base_dir).join(&file[1..]);
//println!("{}", &file);
let path = Path::new(&path);
path.exists()
} else {
false
}
}
#[test]
pub fn runner() {
get_works();
get_full_path_works();
processor_runner();
}
}