diff --git a/Cargo.toml b/Cargo.toml index 032b1b4..8b6b139 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,11 @@ inherits = "release" lto = true [profile.release] -lto = true \ No newline at end of file +lto = true + +[profile.small] +inherits = "release" +lto = true +strip = true +opt-level = "z" +codegen-units = 1 diff --git a/schemsearch-cli/src/main.rs b/schemsearch-cli/src/main.rs index 4ee633b..3708a54 100644 --- a/schemsearch-cli/src/main.rs +++ b/schemsearch-cli/src/main.rs @@ -1,11 +1,8 @@ -use std::fmt::format; use std::fs::File; -use std::io::{BufWriter, Stdout, StdoutLock, Write}; -use clap::{command, Arg, ArgAction, ColorChoice, value_parser, Command}; +use std::io::{BufWriter, StdoutLock, Write}; +use clap::{command, Arg, ArgAction, Command}; use schemsearch_files::Schematic; -use schemsearch_lib::pattern_mapper::match_palette; use std::path::Path; -use clap::ArgAction::Help; use clap::error::ErrorKind; use schemsearch_lib::{search, SearchBehavior}; @@ -65,7 +62,7 @@ fn main() { .long("output") .action(ArgAction::Append) .default_value("std") - .value_parser(["std_csv", "file_csv", "std"]), + .value_parser(["std_csv", "file_csv", "std", "file"]), ) .arg( Arg::new("output-file") @@ -125,10 +122,10 @@ fn main() { } }; - let mut stdout = std::io::stdout(); + let stdout = std::io::stdout(); let mut lock = stdout.lock(); - let mut file: Option = None; + let file: Option; let mut file_out: Option> = None; if output_file || output_file_csv { @@ -164,7 +161,7 @@ fn main() { } } } - Err(e) => cmd.error(ErrorKind::Io, "Expected to be a dir").exit() + Err(e) => cmd.error(ErrorKind::Io, format!("Expected to be a dir: {}", e.to_string())).exit() } } else { search_schempath(&mut cmd, search_behavior, &pattern, &mut output_std, &mut output_std_csv, &mut output_file_csv, &mut output_file, &mut lock, &mut file_out, path) @@ -183,21 +180,24 @@ fn search_schempath(cmd: &mut Command, search_behavior: SearchBehavior, pattern: if *output_std { writeln!(stdout, "Searching in schematic: {}", schem_path.file_name().unwrap().to_str().unwrap()).unwrap(); } + if *output_file { + writeln!(file_out.as_mut().unwrap(), "Searching in schematic: {}", schem_path.file_name().unwrap().to_str().unwrap()).unwrap(); + } let matches = search(&schematic, &pattern, search_behavior); for x in matches { if *output_std { - writeln!(stdout, "Found match at x: {}, y: {}, z: {}", x.0, x.1, x.2).unwrap(); + writeln!(stdout, "Found match at x: {}, y: {}, z: {}, % = {}", x.0, x.1, x.2, x.3).unwrap(); } if *output_std_csv { - writeln!(stdout, "{},{},{},{}", schem_path.file_name().unwrap().to_str().unwrap(), x.0, x.1, x.2).unwrap(); + writeln!(stdout, "{},{},{},{},{}", schem_path.file_name().unwrap().to_str().unwrap(), x.0, x.1, x.2, x.3).unwrap(); } if *output_file { - writeln!(file_out.as_mut().unwrap(), "Found match at x: {}, y: {}, z: {}", x.0, x.1, x.2).unwrap(); + writeln!(file_out.as_mut().unwrap(), "Found match at x: {}, y: {}, z: {}, % = {}", x.0, x.1, x.2, x.3).unwrap(); } if *output_file_csv { - writeln!(file_out.as_mut().unwrap(), "{},{},{},{}", schem_path.file_name().unwrap().to_str().unwrap(), x.0, x.1, x.2).unwrap(); + writeln!(file_out.as_mut().unwrap(), "{},{},{},{},{}", schem_path.file_name().unwrap().to_str().unwrap(), x.0, x.1, x.2, x.3).unwrap(); } } } diff --git a/schemsearch-files/src/lib.rs b/schemsearch-files/src/lib.rs index fe005c0..0b90cdb 100644 --- a/schemsearch-files/src/lib.rs +++ b/schemsearch-files/src/lib.rs @@ -1,7 +1,6 @@ use std::path::Path; use nbt::{Map, Value}; use serde::{Deserialize, Deserializer, Serialize}; -use serde::de::Error; #[derive(Serialize, Deserialize, Debug)] pub struct Schematic { diff --git a/schemsearch-java/src/lib.rs b/schemsearch-java/src/lib.rs index 8c1f44f..3c13f0b 100644 --- a/schemsearch-java/src/lib.rs +++ b/schemsearch-java/src/lib.rs @@ -8,14 +8,15 @@ use schemsearch_files::Schematic; use schemsearch_lib::{search, SearchBehavior}; #[no_mangle] +#[allow(unused_variables)] pub extern "system" fn Java_SchemSearch_search<'local>(mut env: JNIEnv<'local>, class: JClass<'local>, schematic_path: JString<'local>, pattern_path: JString<'local>) -> jstring { let schematic_path: String = env.get_string(&schematic_path).expect("Couldn't get java string!").into(); let pattern_path: String = env.get_string(&pattern_path).expect("Couldn't get java string!").into(); - let schematic = Schematic::load(Path::new(&schematic_path)); - let pattern = Schematic::load(Path::new(&pattern_path)); + let schematic = Schematic::load(Path::new(&schematic_path)).unwrap(); + let pattern = Schematic::load(Path::new(&pattern_path)).unwrap(); let matches = search(&schematic, &pattern, SearchBehavior { ignore_block_data: true, @@ -27,8 +28,8 @@ pub extern "system" fn Java_SchemSearch_search<'local>(mut env: JNIEnv<'local>, }); let mut result = String::new(); - for (x, y, z) in matches { - result.push_str(&format!("{}, {}, {};", x, y, z)); + for (x, y, z, p) in matches { + result.push_str(&format!("{}, {}, {}, {};", x, y, z, p)); } result.remove(result.len() - 1); let output = env.new_string(result).expect("Couldn't create java string!"); diff --git a/schemsearch-lib/src/lib.rs b/schemsearch-lib/src/lib.rs index 1811fe5..a1da5a4 100644 --- a/schemsearch-lib/src/lib.rs +++ b/schemsearch-lib/src/lib.rs @@ -17,7 +17,7 @@ pub fn search( schem: &Schematic, pattern_schem: &Schematic, search_behavior: SearchBehavior, -) -> Vec<(u16, u16, u16)> { +) -> Vec<(u16, u16, u16, f64)> { if schem.width < pattern_schem.width || schem.height < pattern_schem.height || schem.length < pattern_schem.length { return vec![]; } @@ -31,7 +31,7 @@ pub fn search( None => return vec![], }; - let mut matches: Vec<(u16, u16, u16)> = Vec::new(); + let mut matches: Vec<(u16, u16, u16, f64)> = Vec::new(); let pattern_data = pattern_schem.block_data; let schem_data = &schem.block_data; @@ -56,8 +56,9 @@ pub fn search( } } } - if matching as f64 / pattern_blocks > search_behavior.threshold { - matches.push((x as u16, y as u16, z as u16)); + let matching_percent = matching as f64 / pattern_blocks; + if matching_percent > search_behavior.threshold { + matches.push((x as u16, y as u16, z as u16, matching_percent)); } } } @@ -70,7 +71,7 @@ pub fn normalize_data(data: &String, ignore_data: bool) -> String { if ignore_data { data.split('[').next().unwrap().to_string() } else { - data.clone() + data.to_string() } } @@ -93,7 +94,7 @@ mod tests { #[test] fn read_schematic() { - let schematic = Schematic::load(Path::new("../tests/simple.schem")); + let schematic = Schematic::load(Path::new("../tests/simple.schem")).unwrap(); assert_eq!(schematic.width as usize * schematic.height as usize * schematic.length as usize, schematic.block_data.len()); assert_eq!(schematic.palette_max, schematic.palette.len() as i32); } @@ -108,7 +109,7 @@ mod tests { #[test] fn test_strip_schem() { - let schematic = Schematic::load(Path::new("../tests/simple.schem")); + let schematic = Schematic::load(Path::new("../tests/simple.schem")).unwrap(); let stripped = strip_data(&schematic); assert_eq!(stripped.palette.keys().any(|k| k.contains('[')), false); @@ -116,28 +117,26 @@ mod tests { #[test] fn test_match_palette() { - let schematic = Schematic::load(Path::new("../tests/simple.schem")); - let endstone = Schematic::load(Path::new("../tests/endstone.schem")); + let schematic = Schematic::load(Path::new("../tests/simple.schem")).unwrap(); + let endstone = Schematic::load(Path::new("../tests/endstone.schem")).unwrap(); - let matched_schematic = match_palette(&schematic, &endstone, true); + let _ = match_palette(&schematic, &endstone, true); } #[test] fn test_match_palette_ignore_data() { - let schematic = Schematic::load(Path::new("../tests/simple.schem")); - let endstone = Schematic::load(Path::new("../tests/endstone.schem")); + let schematic = Schematic::load(Path::new("../tests/simple.schem")).unwrap(); + let endstone = Schematic::load(Path::new("../tests/endstone.schem")).unwrap(); - let matched_schematic = match_palette(&schematic, &endstone, false); + let _ = match_palette(&schematic, &endstone, false); } #[test] pub fn test_big_search() { - let file = std::fs::File::open("../tests/simple.schem").expect("Failed to open file"); - let schematic = &std::io::Read::bytes(file).map(|b| b.unwrap()).collect(); - let file = std::fs::File::open("../tests/endstone.schem").expect("Failed to open file"); - let pattern = &std::io::Read::bytes(file).map(|b| b.unwrap()).collect(); + let schematic = Schematic::load(Path::new("../tests/simple.schem")).unwrap(); + let endstone = Schematic::load(Path::new("../tests/endstone.schem")).unwrap(); - let matches = search(schematic, pattern, SearchBehavior { + let _ = search(&schematic, &endstone, SearchBehavior { ignore_block_data: true, ignore_block_entities: true, ignore_entities: true, @@ -149,12 +148,10 @@ mod tests { #[test] pub fn test_search() { - let file = std::fs::File::open("../tests/Random.schem").expect("Failed to open file"); - let schematic = &std::io::Read::bytes(file).map(|b| b.unwrap()).collect(); - let file = std::fs::File::open("../tests/Pattern.schem").expect("Failed to open file"); - let pattern = &std::io::Read::bytes(file).map(|b| b.unwrap()).collect(); + let schematic = Schematic::load(Path::new("../tests/Random.schem")).unwrap(); + let pattern = Schematic::load(Path::new("../tests/Pattern.schem")).unwrap(); - let matches = search(schematic, pattern, SearchBehavior { + let matches = search(&schematic, &pattern, SearchBehavior { ignore_block_data: true, ignore_block_entities: true, ignore_entities: true, @@ -165,6 +162,6 @@ mod tests { println!("{:?}", matches); assert_eq!(matches.len(), 1); - assert_eq!(matches[0], (1, 0, 3)); + assert_eq!(matches[0], (1, 0, 3, 1.0)); } }