use rusqlite::Connection; use std::fs; use crate::db::get_db_path; #[derive(PartialEq)] pub struct DictionaryEntry { hieroglyph: String, reading: String, translation: String, } impl std::clone::Clone for DictionaryEntry { fn clone(&self) -> Self { Self { hieroglyph: self.hieroglyph.clone(), reading: self.reading.clone(), translation: self.translation.clone(), } } } impl std::fmt::Display for DictionaryEntry { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{}:{}:{}", self.hieroglyph, self.reading, self.translation ) } } fn get_sym_pos_or_panic(path: &String, line: &str, sym: &str, line_number: usize) -> usize { match line.find(sym) { Some(c) => c, None => panic!( "Failed to parse {} on line {}. Cannot find '{}'.", path, line_number, sym ), } } fn read_and_parse(path: &String) -> Vec { let mut result: Vec = Vec::new(); let content = fs::read_to_string(path).unwrap(); let content: Vec<&str> = content.split('\n').collect(); for (line_number, line) in content.iter().enumerate() { if line == &"" { continue; } let hieroglyph_start = get_sym_pos_or_panic(path, line, "(", line_number) + 1; let hieroglyph_end = get_sym_pos_or_panic(path, line, ")", line_number); let reading_start = get_sym_pos_or_panic(path, line, "[", line_number) + 1; let reading_end = get_sym_pos_or_panic(path, line, "]", line_number); let translation_start = get_sym_pos_or_panic(path, line, "{", line_number) + 1; let translation_end = get_sym_pos_or_panic(path, line, "}", line_number); let hieroglyph = line[hieroglyph_start..hieroglyph_end].to_string(); let reading = if reading_start == reading_end { String::from("") } else { line[reading_start..reading_end].to_string() }; let translation = line[translation_start..translation_end].to_string(); let entry = DictionaryEntry { hieroglyph, reading, translation, }; result.push(entry); } result } fn deduplicate(entries: &Vec) -> Vec { let mut deduplicated: Vec = Vec::new(); for entry in entries.iter() { let mut is_dup = false; for e in deduplicated.iter() { if e.hieroglyph == entry.hieroglyph { is_dup = true; break; } } if is_dup { let pos = deduplicated .iter() .position(|x| x.hieroglyph == entry.hieroglyph) .unwrap(); deduplicated[pos].translation += &(String::from(";") + &entry.translation); } else { deduplicated.push(entry.clone()); } } deduplicated } fn write_to_database(dict: &Vec) { let conn = Connection::open(get_db_path()).unwrap(); for line in dict.iter() { match conn.execute("INSERT OR REPLACE INTO cards (id, hieroglyph, reading, translation) VALUES ((SELECT id FROM cards WHERE hieroglyph = ?1), ?1, ?2, ?3)", [&line.hieroglyph, &line.reading, &line.translation]) { Ok(_) => (), Err(e) => { println!("{e}" ); panic!("Cannot update database with words form dictionary") } }; } } pub fn import(path: &String) { let dictionary = read_and_parse(path); let dictionary = deduplicate(&dictionary); // write_to_database(&dictionary); } // pub fn write_to_file(path: &String, dict: &Vec) { // let mut output = OpenOptions::new() // .write(true) // .append(true) // .open("./reparsed-test.txt") // .unwrap(); // for entry in dict { // if let Err(e) = writeln!( // output, // "({}) [{}] {{{}}}", // entry.hieroglyph, entry.reading, entry.translation // ) { // eprintln!("Couldn't write to file: {}", e); // } // } // }