feat: word lang included to allow better filtering

This commit is contained in:
2026-07-26 12:07:52 +02:00
parent 29ea04aed6
commit 9ccc447c64
2 changed files with 80 additions and 18 deletions

View File

@@ -34,21 +34,48 @@ fn main() {
match word_source_result { match word_source_result {
Ok(word_source) => { Ok(word_source) => {
// NOTE: test initial state
println!(">> Test word init");
if let Ok(w_list) = word_source.find_by_word("test") { if let Ok(w_list) = word_source.find_by_word("test") {
println!("Words! {:?}", w_list); println!("Words! {:?}", w_list);
} }
let _ = word_source.edit_word(Word("test".to_string(), "This is a test".to_string()));
let _ = word_source.edit_word(Word("test2".to_string(), "This is a test".to_string())); // NOTE: test insert
let _ = word_source.insert_word(Word("test".to_string(), "This is a test".to_string())); println!(">> Test word insert");
let _ = let _ = word_source.insert_word(Word {
word_source.insert_word(Word("test3".to_string(), "This is a test".to_string())); key: "test".to_string(),
description: "This is a test".to_string(),
lang: "en".to_string(),
});
let _ = word_source.insert_word(Word {
key: "test 2".to_string(),
description: "This is a test".to_string(),
lang: "es".to_string(),
});
let _ = word_source.insert_word(Word {
key: "another test".to_string(),
description: "This is a test".to_string(),
lang: "es".to_string(),
});
if let Ok(w_list) = word_source.find_by_word("test") { if let Ok(w_list) = word_source.find_by_word("test") {
println!("Words! {:?}", w_list); println!("Words! {:?}", w_list);
} }
// NOTE: test edit
println!(">> Test word edit");
let _ = word_source.edit_word(Word {
key: "test".to_string(),
description: "This is a test".to_string(),
lang: "es".to_string(),
});
if let Ok(w_list) = word_source.find_by_word("test") {
println!("Words! {:?}", w_list);
}
// NOTE: test remove
println!(">> Test word remove");
let _ = word_source.remove_word("test2"); let _ = word_source.remove_word("test2");
if let Ok(w_list) = word_source.find_by_word("test") {
println!("Words! {:?}", w_list);
}
let _ = word_source.remove_word("test"); let _ = word_source.remove_word("test");
if let Ok(w_list) = word_source.find_by_word("test") { if let Ok(w_list) = word_source.find_by_word("test") {
println!("Words! {:?}", w_list); println!("Words! {:?}", w_list);

View File

@@ -1,7 +1,11 @@
use rusqlite::{Connection, params}; use rusqlite::{Connection, params};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Word(pub String, pub String); pub struct Word {
pub key: String,
pub description: String,
pub lang: String,
}
pub struct FileDatabase { pub struct FileDatabase {
connection: Connection, connection: Connection,
@@ -33,7 +37,8 @@ impl FileDatabase {
.execute( .execute(
"CREATE TABLE IF NOT EXISTS word ( "CREATE TABLE IF NOT EXISTS word (
key TEXT PRIMARY KEY, key TEXT PRIMARY KEY,
description TEXT NOT NULL description TEXT NOT NULL,
lang VARCHAR(2) NOT NULL
)", )",
(), // empty list of parameters. (), // empty list of parameters.
) )
@@ -48,8 +53,10 @@ pub trait WordSource {
fn edit_word(&self, word: Word) -> Result<Word, ()>; fn edit_word(&self, word: Word) -> Result<Word, ()>;
fn get_all_words(&self) -> Vec<Word>; fn get_all_words(&self) -> Vec<Word>;
fn normalize_word_key(word_key: &str) -> String; fn normalize_word_key(word_key: &str) -> String;
fn normalize_lang_key(word_key: &str) -> String;
} }
// TODO: improve fuzzy
fn fuzzy_compare(a: &str, b: &str) -> bool { fn fuzzy_compare(a: &str, b: &str) -> bool {
if a.eq(b) || a.contains(b) || b.contains(a) { if a.eq(b) || a.contains(b) || b.contains(a) {
return true; return true;
@@ -59,7 +66,9 @@ fn fuzzy_compare(a: &str, b: &str) -> bool {
impl WordSource for FileDatabase { impl WordSource for FileDatabase {
fn find_by_word(&self, word: &str) -> Result<Vec<Word>, ()> { fn find_by_word(&self, word: &str) -> Result<Vec<Word>, ()> {
let statement = self.connection.prepare("SELECT key, description FROM word"); let statement = self
.connection
.prepare("SELECT key, description, lang FROM word");
let mut word_list: Vec<Word> = vec![]; let mut word_list: Vec<Word> = vec![];
if let Ok(mut query) = statement { if let Ok(mut query) = statement {
@@ -68,7 +77,12 @@ impl WordSource for FileDatabase {
let found_word: String = row.get(0).unwrap(); let found_word: String = row.get(0).unwrap();
if fuzzy_compare(word, &found_word) { if fuzzy_compare(word, &found_word) {
let found_word_description: String = row.get(1).unwrap(); let found_word_description: String = row.get(1).unwrap();
word_list.push(Word(found_word, found_word_description)); let found_word_lang: String = row.get(2).unwrap();
word_list.push(Word {
key: found_word,
description: found_word_description,
lang: found_word_lang,
});
} }
} }
} else { } else {
@@ -79,8 +93,12 @@ impl WordSource for FileDatabase {
fn insert_word(&self, word: Word) -> Result<(), ()> { fn insert_word(&self, word: Word) -> Result<(), ()> {
let result = self.connection.execute( let result = self.connection.execute(
"INSERT INTO word (key, description) VALUES (?1, ?2)", "INSERT INTO word (key, description, lang) VALUES (?1, ?2, ?3)",
(&Self::normalize_word_key(&word.0), &word.1), (
&Self::normalize_word_key(&word.key),
&word.description,
&Self::normalize_lang_key(&word.lang),
),
); );
if let Ok(count) = result { if let Ok(count) = result {
if count > 0 { if count > 0 {
@@ -92,8 +110,12 @@ impl WordSource for FileDatabase {
fn edit_word(&self, word: Word) -> Result<Word, ()> { fn edit_word(&self, word: Word) -> Result<Word, ()> {
let result = self.connection.execute( let result = self.connection.execute(
"UPDATE word SET key = ?1, description = ?2 WHERE key = ?1", "UPDATE word SET key = ?1, description = ?2, lang = ?3 WHERE key = ?1",
(&Self::normalize_word_key(&word.0), &word.1), (
&Self::normalize_word_key(&word.key),
&word.description,
&Self::normalize_lang_key(&word.lang),
),
); );
match result { match result {
Ok(_) => { Ok(_) => {
@@ -121,7 +143,9 @@ impl WordSource for FileDatabase {
} }
fn get_all_words(&self) -> Vec<Word> { fn get_all_words(&self) -> Vec<Word> {
let statement = self.connection.prepare("select key, description from word"); let statement = self
.connection
.prepare("select key, description, lang from word");
let mut word_list: Vec<Word> = vec![]; let mut word_list: Vec<Word> = vec![];
// TODO: make this pretty with functional programming // TODO: make this pretty with functional programming
@@ -130,7 +154,12 @@ impl WordSource for FileDatabase {
while let Some(row) = rows.next().unwrap() { while let Some(row) = rows.next().unwrap() {
let found_word: String = row.get(0).unwrap(); let found_word: String = row.get(0).unwrap();
let found_word_description: String = row.get(1).unwrap(); let found_word_description: String = row.get(1).unwrap();
word_list.push(Word(found_word, found_word_description)); let found_word_lang: String = row.get(2).unwrap();
word_list.push(Word {
key: found_word,
description: found_word_description,
lang: found_word_lang,
});
} }
} }
@@ -142,4 +171,10 @@ impl WordSource for FileDatabase {
// final and real word -> Maybe full refactor to include a word id // final and real word -> Maybe full refactor to include a word id
word_key.to_lowercase().to_string() word_key.to_lowercase().to_string()
} }
fn normalize_lang_key(word_key: &str) -> String {
// TODO: real normalization, not just lowercase, but keep in mind it must be kept as the
// final and real word -> Maybe full refactor to include a word id
word_key.to_lowercase().to_string()
}
} }