use std::io;
mod word_process;
use word_process::*;
use std::collections::HashMap;
#[cfg(debug_assertions)]
use std::time;
use std::sync::{mpsc, Arc};
use std::thread;
fn main() {
println!("Check word: ");
let mut input = String::new();
let result = io::stdin().read_line(&mut input);
if let Err(e) = result{
println!("read_line error: {}", e);
}
#[cfg(debug_assertions)]
let timer = time::Instant::now(); let word = first_word(&input).to_lowercase();
if word.len() < 2 { println!("input is too short"); return (); }
let mut num_print_def = 5_u32; let num_search_def = 10_u32;
let wordsims: Vec<WordSim> = check_against(&word, num_search_def, 4).into_iter().rev().collect();
#[cfg(debug_assertions)]
let silent_failed_def_threads: Arc<u32> = Arc::new(0_u32);
#[cfg(debug_assertions)]
let total_def_thread_count = wordsims.len();
let (tx, rx) = mpsc::channel(); let mut word_defs: HashMap<String, Vec<WordDef>> = HashMap::new();
let client = Arc::new(reqwest::blocking::Client::new());
for wordsim in wordsims.iter() {
let (word_2, sender, client_ref) = (
wordsim.get_word_2().to_string(),
tx.clone(),
client.clone(),
);
#[cfg(debug_assertions)]
let mut fail_count = silent_failed_def_threads.clone();
let _ = thread::Builder::new()
.name(format!("Getting def for word {}", &word_2))
.spawn(move || {
let word_defs = 'def_get: {
for _ in 0..3 {
let word_defs = get_word_defs(&word_2, 2_u32, &*client_ref);
match word_defs{
Ok(defs) => break 'def_get defs,
Err(e) if *e.to_string() == "error code: 502\n".to_string() => continue,
Err(e) => panic!("unknown error: {}", e),
}
}
#[cfg(debug_assertions)]
{ *Arc::make_mut(&mut fail_count) += 1_u32; }
return ();
};
let def_data = (
word_2.to_string(),
word_defs,
);
let mut there_is_a_def = false;
for def in def_data.1.iter() {
there_is_a_def |= def.def.is_some();
}
if there_is_a_def { sender.send(def_data).unwrap(); }
}
);
}
std::mem::drop(tx);
for def in rx{
word_defs.insert(def.0, def.1);
}
println!("");
let mut wordsims_iter = wordsims.into_iter();
match wordsims_iter.next() {
Some(wordsim) => {
if wordsim.get_sim() == 1.0/0.0 &&
word_defs.get(wordsim.get_word_1()).is_some(){
println!("✅ '{word}' IS a word ✅");
println!("Definition of {word}");
print_def(&wordsim, &word_defs, false);
println!("Simmalar words:\n");
} else {
println!("❌ '{word}' is NOT a word ❌");
println!("Simmalar words:\n");
print_def(&wordsim, &word_defs, true);
}
}
None => {
println!("No matches found for '{word}'");
return;
}
}
for wordsim in wordsims_iter{
print_def(&wordsim, &word_defs, true);
num_print_def -= 1;
if num_print_def == 0 {
break;
}
}
#[cfg(debug_assertions)]
{
println!("Took {} millis to run", timer.elapsed().as_millis());
println!(
"{}/{} def threads failed silently",
Arc::<u32>::into_inner(silent_failed_def_threads).unwrap(),
total_def_thread_count
);
}
}
fn print_def(wordsim: &WordSim, lookup: &HashMap<String, Vec<WordDef>>, display_sim: bool) {
let word = wordsim.get_word_1();
let word2 = wordsim.get_word_2();
let defs = lookup.get(word2);
if defs.is_none() {
return;
}
let defs = defs.unwrap();
let mut def_text = String::new();
for def in defs.iter() {
if let Some(some_speech) = &def.part_of_speech{
if let Some(some_def) = &def.def{
def_text.push_str(
&format!("> {}: {}\n",
some_speech,
some_def,
)
);
}
}
}
if display_sim {
def_text = format!(
"'{word}' is {}% simmalar to the word '{}'\n{}",
wordsim.get_sim() * 100.0,
wordsim.get_word_2(),
def_text,
);
}
println!("{}", def_text);
}