use once_cell::sync::Lazy;
use regex::Regex;
use std::collections::HashMap;
const PAD: char = '$';
const PUNCTUATION: &str = ";:,.!?¡¿—…\u{201C}«»\u{201D}\" ";
const LETTERS: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const IPA_LETTERS: &str =
"ɑɐɒæɓʙβɔɕçɗɖðʤəɘɚɛɜɝɞɟʄɡɠɢʛɦɧħɥʜɨɪʝɭɬɫɮʟɱɯɰŋɳɲɴøɵɸθœɶʘɹɺɾɻʀʁɽʂʃʈʧʉʊʋⱱʌɣɤʍχʎʏʑʐʒʔʡʕʢǀǁǂǃˈˌːˑʼʴʰʱʲʷˠˤ˞↓↑→↗↘\u{2019}\u{0329}\u{2018}ᵻ";
static VOCAB: Lazy<HashMap<char, i64>> = Lazy::new(|| {
let symbols: Vec<char> = std::iter::once(PAD)
.chain(PUNCTUATION.chars())
.chain(LETTERS.chars())
.chain(IPA_LETTERS.chars())
.collect();
symbols
.into_iter()
.enumerate()
.map(|(i, c)| (c, i as i64))
.collect()
});
static RE_TOKENIZE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\w+|[^\w\s]").expect("regex"));
pub fn ipa_to_ids(ipa: &str) -> Vec<i64> {
let tokenized = RE_TOKENIZE
.find_iter(ipa)
.map(|m| m.as_str())
.collect::<Vec<_>>()
.join(" ");
let mut ids = vec![0i64];
for ch in tokenized.chars() {
if let Some(id) = VOCAB.get(&ch) {
ids.push(*id);
}
}
ids.push(0i64);
ids
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pads_present() {
let ids = ipa_to_ids("hɛloʊ");
assert_eq!(ids[0], 0);
assert_eq!(*ids.last().unwrap(), 0);
assert!(ids.len() > 2);
}
#[test]
fn pad_char_is_zero() {
assert_eq!(VOCAB.get(&'$').copied(), Some(0));
}
}