Skip to content

Commit

Permalink
Added untested ability to apply >1 affix pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Jan 1, 2023
1 parent 8708e87 commit da4058e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 32 deletions.
4 changes: 2 additions & 2 deletions crates/zspell/src/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ use crate::{suggestions, ParsedCfg};
/// Internally, this is represented as the following:
///
/// - A main wordlist
/// - A list of words to accept byt never suggest
/// - A list of words to accept but never suggest, from the `NOSUGGEST` flag
/// - A list of words that are usually allowed but are forbidden by a personal
/// dictionary
/// dictionary or the `FORBIDDENWORD` flag
/// - A list of stem words and source information
/// - Configuration information
///
Expand Down
59 changes: 34 additions & 25 deletions crates/zspell/src/dict/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,46 @@ pub(super) fn create_affixed_word_map(
}

// Store words with prefixes that can also have suffixes
let mut prefixed_words: Vec<(String, &Arc<AfxRule>)> = Vec::new();
let mut prefixed_words: Vec<(String, &Arc<AfxRule>, usize)> = Vec::new();
let mut rule_found = false;

for &rule in prefix_rules.iter() {
let result = rule.apply_pattern(stem).ok_or(())?;
let meta = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta_vec = dest.0.entry_ref(&result).or_insert_with(Vec::new);
meta_vec.push(meta);

if rule.can_combine() {
prefixed_words.push((result, rule));
for (idx, result) in rule.apply_patterns(stem) {
let meta = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta_vec = dest.0.entry_ref(&result).or_insert_with(Vec::new);
meta_vec.push(meta);
rule_found = true;

if rule.can_combine() {
prefixed_words.push((result, rule, idx));
}
}
}

for &rule in suffix_rules.iter() {
let result = rule.apply_pattern(stem).ok_or(())?;
let meta = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta_vec = dest.0.entry_ref(&result).or_insert_with(Vec::new);
meta_vec.push(meta);

if rule.can_combine() {
let words_iter = prefixed_words.iter().filter_map(|(tmp_res, pfx_rule)| {
rule.apply_pattern(tmp_res)
.map(|newword| (newword, pfx_rule))
});

for (newword, &pfx_rule) in words_iter {
let meta_vec = dest.0.entry_ref(&newword).or_insert_with(Vec::new);
let meta1 = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta2 = Meta::new(stem_rc.clone(), Source::Affix(pfx_rule.clone()));
meta_vec.push(meta1);
meta_vec.push(meta2);
for (idx, result) in rule.apply_patterns(stem) {
let meta = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta_vec = dest.0.entry_ref(&result).or_insert_with(Vec::new);
meta_vec.push(meta);
rule_found = true;

if rule.can_combine() {
// Find words where there's both a prefix and suffix applicable
let words_iter = prefixed_words
.iter()
.map(|(tmp_res, pfx_rule, idx_pfx)| {
rule.apply_patterns(tmp_res)
.map(move |(idx_sfx, newword)| (newword, pfx_rule, idx_pfx, idx_sfx))
})
.flatten();

for (newword, &pfx_rule, _idx_pfx, _idx_sfx) in words_iter {
let meta_vec = dest.0.entry_ref(&newword).or_insert_with(Vec::new);
let meta1 = Meta::new(stem_rc.clone(), Source::Affix(rule.clone()));
let meta2 = Meta::new(stem_rc.clone(), Source::Affix(pfx_rule.clone()));
meta_vec.push(meta1);
meta_vec.push(meta2);
}
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions crates/zspell/src/dict/rule.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implementation for a store rule
//! Implementation for a stored rule

use std::hash::Hash;
use std::ops::Deref;
Expand Down Expand Up @@ -88,15 +88,20 @@ impl AfxRule {
self.can_combine
}

/// Apply one of this rule's patterns, error if none apply
pub fn apply_pattern(&self, stem: &str) -> Option<String> {
/// Apply this rules patterns. Returns an iterator over the index of the
/// pattern and the resulting string
pub fn apply_patterns<'a>(
&'a self,
stem: &'a str,
) -> impl Iterator<Item = (usize, String)> + 'a {
self.patterns
.iter()
.find_map(|pat| pat.apply_pattern(stem, self.kind))
.enumerate()
.filter_map(|(idx, pat)| pat.apply_pattern(stem, self.kind).map(|s| (idx, s)))
}
}

/// A single rule
/// A single affix rule application
#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
pub struct AfxRulePattern {
affix: String,
Expand Down

0 comments on commit da4058e

Please sign in to comment.