use std::collections::HashMap;
use serde::Deserialize;
use crate::error::Result;
use crate::models::sparse::stemmer::stem;
#[derive(Deserialize)]
struct Schema {
vocab: Vec<String>,
stem_mapping: HashMap<String, String>,
}
#[derive(Debug)]
pub struct Vocab {
word_ids: HashMap<String, u32>,
stem_mapping: HashMap<String, String>,
len: usize,
}
impl Vocab {
pub fn parse(json: &str) -> Result<Self> {
let schema: Schema = serde_json::from_str(json)?;
let mut word_ids = HashMap::with_capacity(schema.vocab.len());
let mut next_id = 1u32;
for word in schema.vocab {
word_ids.entry(word).or_insert_with(|| {
let id = next_id;
next_id += 1;
id
});
}
Ok(Self {
len: word_ids.len(),
word_ids,
stem_mapping: schema.stem_mapping,
})
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn resolve(&self, word: &str) -> Option<u32> {
if let Some(&id) = self.word_ids.get(word) {
return Some(id);
}
if let Some(canonical) = self.stem_mapping.get(word) {
return self.word_ids.get(canonical).copied();
}
let stemmed = stem(word);
self
.stem_mapping
.get(&stemmed)
.and_then(|canonical| self.word_ids.get(canonical).copied())
}
}
#[cfg(test)]
mod tests;