10 changed files with 167 additions and 30 deletions
@ -0,0 +1,5 @@
|
||||
pub mod dict_en; |
||||
pub mod dict_pl; |
||||
mod encoder; |
||||
|
||||
pub use encoder::*; |
||||
@ -0,0 +1,15 @@
|
||||
use crate::core::major::{Dict, DictEntry}; |
||||
|
||||
pub fn get_dict() -> Dict { |
||||
vec![ |
||||
DictEntry { |
||||
phoneme_in: "EN".to_string(), |
||||
phoneme_out: "2".to_string(), |
||||
not_after: vec!["Y".to_string()], |
||||
not_before: vec!["X".to_string()], |
||||
only_after: vec!["A".to_string()], |
||||
only_before: vec!["C".to_string()], |
||||
}, |
||||
// ...more entries...
|
||||
] |
||||
} |
||||
@ -0,0 +1,15 @@
|
||||
use crate::core::major::{Dict, DictEntry}; |
||||
|
||||
pub fn get_dict() -> Dict { |
||||
vec![ |
||||
DictEntry { |
||||
phoneme_in: "PL".to_string(), |
||||
phoneme_out: "2".to_string(), |
||||
not_after: vec!["Y".to_string()], |
||||
not_before: vec!["X".to_string()], |
||||
only_after: vec!["A".to_string()], |
||||
only_before: vec!["C".to_string()], |
||||
}, |
||||
// ...more entries...
|
||||
] |
||||
} |
||||
@ -0,0 +1,113 @@
|
||||
use crate::core::traits::SystemEncoder; |
||||
|
||||
#[derive(Debug, Default, Clone)] |
||||
pub struct DictEntry { |
||||
pub phoneme_in: String, |
||||
pub phoneme_out: String, |
||||
|
||||
pub not_before: Vec<String>, |
||||
pub not_after: Vec<String>, |
||||
|
||||
pub only_before: Vec<String>, |
||||
pub only_after: Vec<String>, |
||||
} |
||||
|
||||
pub type Dict = Vec<DictEntry>; |
||||
|
||||
/// (index, encoded value)
|
||||
type DictMatches = Vec<(usize, String)>; |
||||
|
||||
pub struct Encoder { |
||||
dict: Dict, |
||||
} |
||||
|
||||
impl Encoder { |
||||
pub fn new(dict: Dict) -> Self { |
||||
Encoder { dict: dict } |
||||
} |
||||
|
||||
fn match_entry(&self, entry: &DictEntry, word: &str) -> DictMatches { |
||||
word.match_indices(&entry.phoneme_in) |
||||
.filter(|(index, _)| self.is_context_matched(&entry, &word, *index)) |
||||
.map(|(index, _)| (index, entry.phoneme_out.clone())) |
||||
.collect() |
||||
} |
||||
|
||||
fn is_context_matched(&self, entry: &DictEntry, word: &str, index: usize) -> bool { |
||||
let before_context = &word[..index]; |
||||
let after_context = &word[index + entry.phoneme_in.len()..]; |
||||
dbg!(&before_context); |
||||
dbg!(&after_context); |
||||
|
||||
if entry |
||||
.not_after |
||||
.iter() |
||||
.any(|prefix| before_context.ends_with(prefix)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if entry |
||||
.not_before |
||||
.iter() |
||||
.any(|suffix| after_context.starts_with(suffix)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if entry |
||||
.only_after |
||||
.iter() |
||||
.all(|prefix| !before_context.ends_with(prefix)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if entry |
||||
.only_before |
||||
.iter() |
||||
.all(|suffix| !after_context.starts_with(suffix)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
true |
||||
} |
||||
} |
||||
|
||||
impl SystemEncoder for Encoder { |
||||
fn encode(&self, word: &str) -> String { |
||||
let mut matches: DictMatches = self |
||||
.dict |
||||
.iter() |
||||
.flat_map(|entry| self.match_entry(&entry, &word)) |
||||
.collect(); |
||||
|
||||
matches.sort_by_key(|&(pos, _)| pos); |
||||
dbg!(&matches); |
||||
matches.into_iter().map(|(_, value)| value).collect() |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
fn create_basic_dict() -> Dict { |
||||
vec![DictEntry { |
||||
phoneme_in: "B".to_string(), |
||||
phoneme_out: "2".to_string(), |
||||
not_after: vec!["Y".to_string()], |
||||
not_before: vec!["X".to_string()], |
||||
only_after: vec!["A".to_string()], |
||||
only_before: vec!["C".to_string()], |
||||
}] |
||||
} |
||||
|
||||
#[test] |
||||
fn test_single_symbol_encoding_all_reqirements_met() { |
||||
let encoder = Encoder::new(create_basic_dict()); |
||||
let output = encoder.encode("ABC"); |
||||
assert_eq!(output, "2") |
||||
} |
||||
} |
||||
@ -0,0 +1,11 @@
|
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
// #[test]
|
||||
// fn test_processing() {
|
||||
// let processor = TextProcessor::new(">> ");
|
||||
// assert_eq!(processor.process("hello"), ">> HELLO");
|
||||
// }
|
||||
} |
||||
@ -1,23 +0,0 @@
|
||||
use crate::core::SystemEncoder; |
||||
|
||||
pub struct MajorEncoder { |
||||
dict: String, // TODO
|
||||
} |
||||
|
||||
impl MajorEncoder { |
||||
pub fn new(dict: &str) -> Self { |
||||
MajorEncoder { |
||||
dict: String::from(dict), |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl SystemEncoder for MajorEncoder { |
||||
fn encode(&self, word: &str) -> String { |
||||
let num_word: String = word |
||||
.chars() |
||||
.map(|c| c.to_digit(10).unwrap_or(0).to_string()) |
||||
.collect(); |
||||
format!("{}_{} -> {}", word, self.dict, num_word) |
||||
} |
||||
} |
||||
@ -1,7 +1,7 @@
|
||||
pub mod major_system_encoder; |
||||
pub mod major; |
||||
pub mod system; |
||||
pub mod system_encoder; |
||||
pub mod traits; |
||||
|
||||
pub use self::major_system_encoder::*; |
||||
pub use self::major::*; |
||||
pub use self::system::*; |
||||
pub use self::system_encoder::*; |
||||
pub use self::traits::*; |
||||
|
||||
Loading…
Reference in new issue