use std::fs; use std::fs::OpenOptions; use std::io::prelude::*; #[derive(PartialEq)] struct Entry { hieroglyph: String, reading: String, translation: String, } impl std::clone::Clone for Entry { fn clone(&self) -> Self { Self { hieroglyph: self.hieroglyph.clone(), reading: self.reading.clone(), translation: self.translation.clone() } } } impl std::fmt::Display for Entry { 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 = Entry { 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 } pub fn import(path: &String) { let mut output = OpenOptions::new() .write(true) .append(true) .open("./reparsed-test.txt") .unwrap(); let dictionary = read_and_parse(path); let dictionary = deduplicate(&dictionary); for entry in dictionary { if let Err(e) = writeln!( output, "({}) [{}] {{{}}}", entry.hieroglyph, entry.reading, entry.translation ) { eprintln!("Couldn't write to file: {}", e); } } }