place asset_tweak behind a feature

This commit is contained in:
juliancoffee 2021-06-08 00:09:29 +03:00
parent 3c34301947
commit 8f86f474e8
3 changed files with 131 additions and 134 deletions

View File

@ -6,7 +6,7 @@ code-quality:
script: script:
- ln -s /dockercache/target target - ln -s /dockercache/target target
- rm -r target/debug/incremental/* || echo "all good" # TMP FIX FOR 2021-03-22-nightly - rm -r target/debug/incremental/* || echo "all good" # TMP FIX FOR 2021-03-22-nightly
- cargo clippy --all-targets --locked --features="bin_csv,bin_bot" -- -D warnings - cargo clippy --all-targets --locked --features="bin_csv,bin_bot,asset_tweak" -- -D warnings
- cargo fmt --all -- --check - cargo fmt --all -- --check
security: security:

View File

@ -14,5 +14,7 @@ dot_vox = "4.0"
image = { version = "0.23.12", default-features = false, features = ["png"] } image = { version = "0.23.12", default-features = false, features = ["png"] }
tracing = "0.1" tracing = "0.1"
[dev-dependencies] serial_test = {version = "0.5", optional = true}
serial_test = "0.5"
[features]
asset_tweak = ["serial_test"]

View File

@ -261,6 +261,7 @@ impl Compound for Directory {
} }
#[warn(clippy::pedantic)] #[warn(clippy::pedantic)]
#[cfg(feature = "asset_tweak")]
pub mod asset_tweak { pub mod asset_tweak {
// Return path to repository by searching 10 directories back // Return path to repository by searching 10 directories back
use super::{find_root, fs, Asset, AssetExt, Path, RonLoader}; use super::{find_root, fs, Asset, AssetExt, Path, RonLoader};
@ -280,8 +281,6 @@ pub mod asset_tweak {
} }
#[must_use] #[must_use]
/// NOTE: Don't use it in production code, it's debug only
///
/// # Usage /// # Usage
/// Create file with content which represent tweaked value /// Create file with content which represent tweaked value
/// ///
@ -299,13 +298,11 @@ pub mod asset_tweak {
/// ///
/// # Panics /// # Panics
/// 1) If given `asset_specifier` does not exists /// 1) If given `asset_specifier` does not exists
/// 2) If asseet is broken
pub fn tweak_expect<T>(specifier: &str) -> T pub fn tweak_expect<T>(specifier: &str) -> T
where where
T: Clone + Sized + Send + Sync + 'static + DeserializeOwned, T: Clone + Sized + Send + Sync + 'static + DeserializeOwned,
{ {
if cfg!(not(any(debug_assertions, test))) {
tracing::warn!("AssetTweaker used in release build!");
}
let asset_specifier: &str = &format!("tweak.{}", specifier); let asset_specifier: &str = &format!("tweak.{}", specifier);
let handle = <AssetTweakWrapper<T> as AssetExt>::load_expect(asset_specifier); let handle = <AssetTweakWrapper<T> as AssetExt>::load_expect(asset_specifier);
let AssetTweakWrapper(value) = handle.read().clone(); let AssetTweakWrapper(value) = handle.read().clone();
@ -313,11 +310,13 @@ pub mod asset_tweak {
} }
#[must_use] #[must_use]
/// NOTE: Don't use it in production code, it's debug only
///
/// # Usage /// # Usage
/// Will create file "assets/tweak/{specifier}.ron" if not exists. /// Will create file "assets/tweak/{specifier}.ron" if not exists
/// If exists will read a value from such file. /// and return passed `value`.
/// If file exists will read a value from such file.
///
/// In release builds (if `debug_assertions` == false) just returns passed
/// `value`
/// ///
/// Example if you want to tweak integer value /// Example if you want to tweak integer value
/// ```no_run /// ```no_run
@ -338,8 +337,7 @@ pub mod asset_tweak {
where where
T: Clone + Sized + Send + Sync + 'static + DeserializeOwned + Serialize, T: Clone + Sized + Send + Sync + 'static + DeserializeOwned + Serialize,
{ {
if cfg!(not(any(debug_assertions, test))) { if cfg!(not(debug_assertions)) {
tracing::warn!("AssetTweaker used in release build!");
return value; return value;
} }
@ -365,143 +363,140 @@ pub mod asset_tweak {
value value
} }
} }
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{find_root, tweak_expect, tweak_expect_or_create};
asset_tweak::{tweak_expect, tweak_expect_or_create}, use serial_test::serial;
find_root, use std::{
}; convert::AsRef,
use serial_test::serial; fmt::Debug,
use std::{ fs::{self, File},
convert::AsRef, io::Write,
fmt::Debug, path::Path,
fs::{self, File}, };
io::Write,
path::Path,
};
struct DirectoryGuard<P> struct DirectoryGuard<P>
where where
P: AsRef<Path>, P: AsRef<Path>,
{ {
dir: P, dir: P,
}
impl<P> DirectoryGuard<P>
where
P: AsRef<Path>,
{
fn create(dir: P) -> Self {
fs::create_dir_all(&dir).expect("failed to create directory");
Self { dir }
}
}
impl<P> Drop for DirectoryGuard<P>
where
P: AsRef<Path>,
{
fn drop(&mut self) { fs::remove_dir(&self.dir).expect("failed to remove directory"); }
}
struct FileGuard<P>
where
P: AsRef<Path> + Debug,
{
file: P,
}
impl<P> FileGuard<P>
where
P: AsRef<Path> + Debug,
{
fn create(file: P) -> (Self, File) {
let f =
File::create(&file).unwrap_or_else(|_| panic!("failed to create file {:?}", &file));
(Self { file }, f)
} }
fn hold(file: P) -> Self { Self { file } } impl<P> DirectoryGuard<P>
} where
P: AsRef<Path>,
impl<P> Drop for FileGuard<P> {
where fn create(dir: P) -> Self {
P: AsRef<Path> + Debug, fs::create_dir_all(&dir).expect("failed to create directory");
{ Self { dir }
fn drop(&mut self) { }
fs::remove_file(&self.file)
.unwrap_or_else(|_| panic!("failed to create file {:?}", &self.file));
} }
}
#[test] impl<P> Drop for DirectoryGuard<P>
#[serial] where
fn test_tweaked_string() { P: AsRef<Path>,
let root = find_root().expect("failed to discover repository_root"); {
let tweak_dir = root.join("assets/tweak/"); fn drop(&mut self) { fs::remove_dir(&self.dir).expect("failed to remove directory"); }
let _dir_guard = DirectoryGuard::create(tweak_dir.clone()); }
// define test files struct FileGuard<P>
let from_int = tweak_dir.join("__test_int_tweak.ron"); where
let from_string = tweak_dir.join("__test_string_tweak.ron"); P: AsRef<Path> + Debug,
let from_map = tweak_dir.join("__test_map_tweak.ron"); {
file: P,
}
// setup fs guards impl<P> FileGuard<P>
let (_file_guard1, mut file1) = FileGuard::create(from_int); where
let (_file_guard2, mut file2) = FileGuard::create(from_string); P: AsRef<Path> + Debug,
let (_file_guard3, mut file3) = FileGuard::create(from_map); {
fn create(file: P) -> (Self, File) {
let f = File::create(&file)
.unwrap_or_else(|_| panic!("failed to create file {:?}", &file));
(Self { file }, f)
}
// write to file and check result fn hold(file: P) -> Self { Self { file } }
file1 }
.write_all(b"(5)")
.expect("failed to write to the file");
let x = tweak_expect::<i32>("__test_int_tweak");
assert_eq!(x, 5);
// write to file and check result impl<P> Drop for FileGuard<P>
file2 where
.write_all(br#"("Hello Zest")"#) P: AsRef<Path> + Debug,
.expect("failed to write to the file"); {
let x = tweak_expect::<String>("__test_string_tweak"); fn drop(&mut self) {
assert_eq!(x, "Hello Zest".to_owned()); fs::remove_file(&self.file)
.unwrap_or_else(|_| panic!("failed to create file {:?}", &self.file));
}
}
// write to file and check result #[test]
file3 #[serial]
.write_all( fn test_tweaked_string() {
br#" let root = find_root().expect("failed to discover repository_root");
let tweak_dir = root.join("assets/tweak/");
let _dir_guard = DirectoryGuard::create(tweak_dir.clone());
// define test files
let from_int = tweak_dir.join("__test_int_tweak.ron");
let from_string = tweak_dir.join("__test_string_tweak.ron");
let from_map = tweak_dir.join("__test_map_tweak.ron");
// setup fs guards
let (_file_guard1, mut file1) = FileGuard::create(from_int);
let (_file_guard2, mut file2) = FileGuard::create(from_string);
let (_file_guard3, mut file3) = FileGuard::create(from_map);
// write to file and check result
file1
.write_all(b"(5)")
.expect("failed to write to the file");
let x = tweak_expect::<i32>("__test_int_tweak");
assert_eq!(x, 5);
// write to file and check result
file2
.write_all(br#"("Hello Zest")"#)
.expect("failed to write to the file");
let x = tweak_expect::<String>("__test_string_tweak");
assert_eq!(x, "Hello Zest".to_owned());
// write to file and check result
file3
.write_all(
br#"
({ ({
"wow": 4, "wow": 4,
"such": 5, "such": 5,
}) })
"#, "#,
) )
.expect("failed to write to the file"); .expect("failed to write to the file");
let x: std::collections::HashMap<String, i32> = tweak_expect("__test_map_tweak"); let x: std::collections::HashMap<String, i32> = tweak_expect("__test_map_tweak");
let mut map = std::collections::HashMap::new(); let mut map = std::collections::HashMap::new();
map.insert("wow".to_owned(), 4); map.insert("wow".to_owned(), 4);
map.insert("such".to_owned(), 5); map.insert("such".to_owned(), 5);
assert_eq!(x, map); assert_eq!(x, map);
} }
#[test] #[test]
#[serial] #[serial]
fn test_tweaked_create() { fn test_tweaked_create() {
let root = find_root().expect("failed to discover repository_root"); let root = find_root().expect("failed to discover repository_root");
let tweak_dir = root.join("assets/tweak/"); let tweak_dir = root.join("assets/tweak/");
let test_path1 = tweak_dir.join("__test_int_create.ron"); let test_path1 = tweak_dir.join("__test_int_create.ron");
let _file_guard1 = FileGuard::hold(&test_path1); let _file_guard1 = FileGuard::hold(&test_path1);
let x = tweak_expect_or_create("__test_int_create", 5); let x = tweak_expect_or_create("__test_int_create", 5);
assert_eq!(x, 5); assert_eq!(x, 5);
assert!(test_path1.is_file()); assert!(test_path1.is_file());
// Test that file has stronger priority // Test that file has stronger priority
let test_path2 = tweak_dir.join("__test_priority.ron"); let test_path2 = tweak_dir.join("__test_priority.ron");
let (_file_guard2, mut file) = FileGuard::create(&test_path2); let (_file_guard2, mut file) = FileGuard::create(&test_path2);
file.write_all(b"(10)") file.write_all(b"(10)")
.expect("failed to write to the file"); .expect("failed to write to the file");
let x = tweak_expect_or_create("__test_priority", 6); let x = tweak_expect_or_create("__test_priority", 6);
assert_eq!(x, 10); assert_eq!(x, 10);
}
} }
} }