|  | use std::{env, fmt::Display, fs};
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | static FORBIDDEN_WORDS: &'static [&'static str] = &[
 | 
						
						
						
							|  | 	"recovery",
 | 
						
						
						
							|  | 	"techie",
 | 
						
						
						
							|  | 	"http",
 | 
						
						
						
							|  | 	"https",
 | 
						
						
						
							|  | 	"digital",
 | 
						
						
						
							|  | 	"hack",
 | 
						
						
						
							|  | 	"::",
 | 
						
						
						
							|  | 	"//",
 | 
						
						
						
							|  | 	"@",
 | 
						
						
						
							|  | 	"com",
 | 
						
						
						
							|  | 	"crypto",
 | 
						
						
						
							|  | 	"bitcoin",
 | 
						
						
						
							|  | 	"wallet",
 | 
						
						
						
							|  | 	"hacker",
 | 
						
						
						
							|  | 	"welcome",
 | 
						
						
						
							|  | 	"whatsapp",
 | 
						
						
						
							|  | 	"email",
 | 
						
						
						
							|  | 	"cryptocurrency",
 | 
						
						
						
							|  | 	"stolen",
 | 
						
						
						
							|  | 	"freeze",
 | 
						
						
						
							|  | 	"quick",
 | 
						
						
						
							|  | 	"crucial",
 | 
						
						
						
							|  | 	"tracing",
 | 
						
						
						
							|  | 	"scammers",
 | 
						
						
						
							|  | 	"expers",
 | 
						
						
						
							|  | 	"hire",
 | 
						
						
						
							|  | 	"century",
 | 
						
						
						
							|  | 	"transaction",
 | 
						
						
						
							|  | 	"essential",
 | 
						
						
						
							|  | 	"managing",
 | 
						
						
						
							|  | 	"contact",
 | 
						
						
						
							|  | 	"contacting",
 | 
						
						
						
							|  | 	"understanding",
 | 
						
						
						
							|  | 	"assets",
 | 
						
						
						
							|  | 	"funds",
 | 
						
						
						
							|  | ];
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | #[derive(Debug, Default)]
 | 
						
						
						
							|  | struct Stats {
 | 
						
						
						
							|  | 	file_count: u32,
 | 
						
						
						
							|  | 	failed_file_count: u32,
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 	sentence_count: u32,
 | 
						
						
						
							|  | 	word_count: u32,
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 	capitalized_count: u32,
 | 
						
						
						
							|  | 	numeric_count: u32,
 | 
						
						
						
							|  | 	forbidden_count: u32,
 | 
						
						
						
							|  | }
 | 
						
						
						
							|  | impl Display for Stats {
 | 
						
						
						
							|  | 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
						
						
						
							|  | 		writeln!(f, "file count: {}", self.file_count)?;
 | 
						
						
						
							|  | 		writeln!(f, "failed file count: {}", self.failed_file_count)?;
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 		writeln!(f, "sentence count: {}", self.sentence_count)?;
 | 
						
						
						
							|  | 		writeln!(f, "word count: {}", self.word_count)?;
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 		writeln!(f, "capitalized count: {}", self.capitalized_count)?;
 | 
						
						
						
							|  | 		writeln!(f, "numeric count: {}", self.numeric_count)?;
 | 
						
						
						
							|  | 		writeln!(f, "forbidden count: {}", self.forbidden_count)?;
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 		let word_count = self.word_count as f32;
 | 
						
						
						
							|  | 		writeln!(
 | 
						
						
						
							|  | 			f,
 | 
						
						
						
							|  | 			"words per sentence average: {:.1}",
 | 
						
						
						
							|  | 			word_count / self.sentence_count as f32
 | 
						
						
						
							|  | 		)?;
 | 
						
						
						
							|  | 		writeln!(
 | 
						
						
						
							|  | 			f,
 | 
						
						
						
							|  | 			"forbidden word percentage: {:.0}%",
 | 
						
						
						
							|  | 			(self.forbidden_count as f32 / word_count) * 100.0,
 | 
						
						
						
							|  | 		)?;
 | 
						
						
						
							|  | 		write!(
 | 
						
						
						
							|  | 			f,
 | 
						
						
						
							|  | 			"capitalized word percentage: {:.0}%",
 | 
						
						
						
							|  | 			(self.capitalized_count as f32 / word_count) * 100.0,
 | 
						
						
						
							|  | 		)
 | 
						
						
						
							|  | 	}
 | 
						
						
						
							|  | }
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | fn main() {
 | 
						
						
						
							|  | 	let files = env::args().skip(1);
 | 
						
						
						
							|  | 	let mut stats = Stats::default();
 | 
						
						
						
							|  | 	for file in files {
 | 
						
						
						
							|  | 		let Ok(text) = fs::read_to_string(&file) else {
 | 
						
						
						
							|  | 			stats.failed_file_count += 1;
 | 
						
						
						
							|  | 			continue;
 | 
						
						
						
							|  | 		};
 | 
						
						
						
							|  | 		stats.file_count += 1;
 | 
						
						
						
							|  | 		for sentence in text
 | 
						
						
						
							|  | 			.split('.')
 | 
						
						
						
							|  | 			.map(|s| s.trim())
 | 
						
						
						
							|  | 			.filter(|s| !s.is_empty())
 | 
						
						
						
							|  | 		{
 | 
						
						
						
							|  | 			stats.sentence_count += 1;
 | 
						
						
						
							|  | 			for word in sentence
 | 
						
						
						
							|  | 				.split_whitespace()
 | 
						
						
						
							|  | 				.map(|s| s.trim())
 | 
						
						
						
							|  | 				.filter(|s| !s.is_empty())
 | 
						
						
						
							|  | 			{
 | 
						
						
						
							|  | 				stats.word_count += 1;
 | 
						
						
						
							|  | 				//get all numbers counted
 | 
						
						
						
							|  | 				let mut all_capitalized = true;
 | 
						
						
						
							|  | 				for char in word.chars() {
 | 
						
						
						
							|  | 					if char.is_numeric() {
 | 
						
						
						
							|  | 						stats.numeric_count += 1;
 | 
						
						
						
							|  | 					}
 | 
						
						
						
							|  | 					if !char.is_ascii_uppercase() {
 | 
						
						
						
							|  | 						all_capitalized = false;
 | 
						
						
						
							|  | 					}
 | 
						
						
						
							|  | 				}
 | 
						
						
						
							|  | 				if all_capitalized {
 | 
						
						
						
							|  | 					stats.capitalized_count += 1;
 | 
						
						
						
							|  | 				}
 | 
						
						
						
							|  | 				let lowercase_word = word.to_lowercase();
 | 
						
						
						
							|  | 				for forbidden_word in FORBIDDEN_WORDS {
 | 
						
						
						
							|  | 					if lowercase_word.contains(forbidden_word) {
 | 
						
						
						
							|  | 						stats.forbidden_count += 1;
 | 
						
						
						
							|  | 					}
 | 
						
						
						
							|  | 				}
 | 
						
						
						
							|  | 			}
 | 
						
						
						
							|  | 		}
 | 
						
						
						
							|  | 	}
 | 
						
						
						
							|  | 	println!("{stats}");
 | 
						
						
						
							|  | }
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | #[test]
 | 
						
						
						
							|  | fn test() {
 | 
						
						
						
							|  | 	use std::{env, fs, process::Command, time::Instant};
 | 
						
						
						
							|  | 	println!("cwd: {}", env::current_dir().unwrap().display());
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 	//compile
 | 
						
						
						
							|  | 	let mut compile = Command::new("cargo");
 | 
						
						
						
							|  | 	let compile_arged = compile.arg("build").arg("--release");
 | 
						
						
						
							|  | 	match compile_arged.output() {
 | 
						
						
						
							|  | 		Ok(output) => println!("compiled {}", String::from_utf8_lossy(&output.stdout)),
 | 
						
						
						
							|  | 		Err(err) => eprintln!("compile failed: {err}"),
 | 
						
						
						
							|  | 	}
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 	//get test files
 | 
						
						
						
							|  | 	let files = fs::read_dir("test_files")
 | 
						
						
						
							|  | 		.unwrap()
 | 
						
						
						
							|  | 		.map(|f| {
 | 
						
						
						
							|  | 			f.unwrap()
 | 
						
						
						
							|  | 				.path()
 | 
						
						
						
							|  | 				.canonicalize()
 | 
						
						
						
							|  | 				.unwrap()
 | 
						
						
						
							|  | 				.to_str()
 | 
						
						
						
							|  | 				.unwrap()
 | 
						
						
						
							|  | 				.to_string()
 | 
						
						
						
							|  | 		})
 | 
						
						
						
							|  | 		.collect::<Vec<_>>();
 | 
						
						
						
							|  | 	println!("test files found: {:#?}", files);
 | 
						
						
						
							|  | 
 | 
						
						
						
							|  | 	//benchmark run
 | 
						
						
						
							|  | 	let benchmark = Instant::now();
 | 
						
						
						
							|  | 	let mut run = Command::new("target/release/jisspam");
 | 
						
						
						
							|  | 	let run_arged = run.args(files);
 | 
						
						
						
							|  | 	match run_arged.output() {
 | 
						
						
						
							|  | 		Ok(output) => println!("{}", String::from_utf8_lossy(&output.stdout)),
 | 
						
						
						
							|  | 		Err(err) => eprintln!("run failed: {err}"),
 | 
						
						
						
							|  | 	}
 | 
						
						
						
							|  | 	println!("benchmark: {}ms", benchmark.elapsed().as_millis());
 | 
						
						
						
							|  | }
 |