mod algorithm;
pub mod articulatory_costs;
mod automaton_zipper;
pub mod builder;
mod builder_api;
pub mod costs_f64;
pub mod generalized;
pub mod helpers;
mod intersection;
mod intersection_f64;
pub mod intersection_zipper;
pub mod operation_set;
pub mod operation_type;
mod ordered_query;
pub mod phonetic;
#[cfg(feature = "phonetic-rules")]
pub mod phonetic_transducer;
mod pool;
mod pool_f64;
mod position;
mod position_f64;
mod priority_query;
mod query;
mod query_f64;
mod query_result;
mod state;
mod state_f64;
pub mod substitution_policy;
pub mod substitution_set;
pub mod substitution_set_char;
pub mod transition;
pub mod transition_f64;
pub mod universal;
mod value_filtered_query;
mod zipper_query_iterator;
#[cfg(target_arch = "x86_64")]
pub mod simd;
pub use algorithm::Algorithm;
pub use articulatory_costs::ArticulatoryCosts;
pub use automaton_zipper::AutomatonZipper;
pub use builder::{BuilderError, TransducerBuilder};
pub use builder_api::QueryBuilder;
pub use costs_f64::OperationCostsF64;
pub use intersection::{Intersection, PathNode};
pub use intersection_f64::IntersectionF64;
pub use intersection_zipper::IntersectionZipper;
pub use operation_set::{OperationSet, OperationSetBuilder};
pub use operation_type::OperationType;
pub use ordered_query::{OrderedCandidate, OrderedQueryIterator};
pub use pool::StatePool;
pub use pool_f64::StatePoolF64;
pub use position::Position;
pub use position_f64::PositionF64;
pub use priority_query::{priority_query, PriorityCandidate, PriorityQueryIterator};
pub use query::{Candidate, CandidateIterator, QueryIterator, StringQueryIterator};
pub use query_f64::{
CandidateF64, CandidateIteratorF64, QueryIteratorF64, QueryResultF64, StringQueryIteratorF64,
};
pub use query_result::QueryResult;
pub use state::State;
pub use state_f64::StateF64;
pub use substitution_policy::{
Restricted, RestrictedChar, SubstitutionPolicy, SubstitutionPolicyChar, SubstitutionPolicyFor,
Unrestricted,
};
pub use substitution_set::SubstitutionSet;
pub use substitution_set_char::SubstitutionSetChar;
pub use transition_f64::{
initial_state_f64, transition_position_f64, transition_state_f64, transition_state_pooled_f64,
};
pub use value_filtered_query::{
ValueFilteredQueryIterator, ValueSetFilteredQueryIterator, ValueYieldingQueryIterator,
};
pub use zipper_query_iterator::ZipperQueryIterator;
#[cfg(feature = "phonetic-rules")]
pub use phonetic_transducer::{
PhoneticCandidate, PhoneticCandidateByte, PhoneticQueryIterator, PhoneticQueryIteratorChar,
PhoneticTransducer, PhoneticTransducerChar,
};
use libdictenstein::{Dictionary, DictionaryNode, MappedDictionary, MappedDictionaryNode};
use std::collections::HashSet;
#[derive(Clone, Debug)]
pub struct Transducer<D: Dictionary, P: SubstitutionPolicy = Unrestricted> {
dictionary: D,
algorithm: Algorithm,
policy: P,
}
impl<D: Dictionary> Transducer<D, Unrestricted>
where
Unrestricted: SubstitutionPolicyFor<<D::Node as DictionaryNode>::Unit>,
{
pub fn new(dictionary: D, algorithm: Algorithm) -> Self {
Self {
dictionary,
algorithm,
policy: Unrestricted,
}
}
pub fn standard(dictionary: D) -> Self {
Self::new(dictionary, Algorithm::Standard)
}
pub fn with_transposition(dictionary: D) -> Self {
Self::new(dictionary, Algorithm::Transposition)
}
pub fn with_merge_split(dictionary: D) -> Self {
Self::new(dictionary, Algorithm::MergeAndSplit)
}
pub fn with_substitutions(
dictionary: D,
algorithm: Algorithm,
substitution_set: SubstitutionSet,
) -> Transducer<D, Restricted<'static>>
where
<D::Node as DictionaryNode>::Unit: From<u8>,
Restricted<'static>: SubstitutionPolicyFor<<D::Node as DictionaryNode>::Unit>,
{
let set: &'static SubstitutionSet = Box::leak(Box::new(substitution_set));
let policy = Restricted::new(set);
Transducer::with_policy(dictionary, algorithm, policy)
}
}
impl<
D: Dictionary,
P: SubstitutionPolicy + SubstitutionPolicyFor<<D::Node as DictionaryNode>::Unit>,
> Transducer<D, P>
{
pub fn with_policy(dictionary: D, algorithm: Algorithm, policy: P) -> Self {
Self {
dictionary,
algorithm,
policy,
}
}
pub fn algorithm(&self) -> Algorithm {
self.algorithm
}
pub fn dictionary(&self) -> &D {
&self.dictionary
}
#[inline]
pub fn into_inner(self) -> D {
self.dictionary
}
#[inline]
pub fn into_dictionary(self) -> D {
self.dictionary
}
pub fn query_builder(&self, term: impl Into<String>) -> QueryBuilder<'_, D> {
QueryBuilder::new(&self.dictionary, term, 2, self.algorithm)
}
pub fn query(&self, term: &str, max_distance: usize) -> QueryIterator<D::Node, String, P> {
QueryIterator::with_policy_and_substring(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
self.policy,
self.dictionary.is_suffix_based(),
)
}
pub fn query_with_distance(
&self,
term: &str,
max_distance: usize,
) -> QueryIterator<D::Node, Candidate, P> {
QueryIterator::with_policy_and_substring(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
self.policy,
self.dictionary.is_suffix_based(),
)
}
pub fn query_ordered(
&self,
term: &str,
max_distance: usize,
) -> OrderedQueryIterator<D::Node, P> {
OrderedQueryIterator::with_policy_and_substring(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
self.policy,
self.dictionary.is_suffix_based(),
)
}
pub fn query_terms(
&self,
term: &str,
max_distance: usize,
) -> QueryIterator<D::Node, String, P> {
self.query(term, max_distance)
}
pub fn query_candidates(
&self,
term: &str,
max_distance: usize,
) -> QueryIterator<D::Node, Candidate, P> {
self.query_with_distance(term, max_distance)
}
pub fn query_ranked(
&self,
term: &str,
max_distance: usize,
) -> OrderedQueryIterator<D::Node, P> {
self.query_ordered(term, max_distance)
}
}
impl<D, P> Transducer<D, P>
where
D: MappedDictionary,
D::Node: MappedDictionaryNode<Value = D::Value>,
P: SubstitutionPolicy + SubstitutionPolicyFor<<D::Node as DictionaryNode>::Unit>,
{
pub fn query_filtered<F>(
&self,
term: &str,
max_distance: usize,
filter: F,
) -> ValueFilteredQueryIterator<D::Node, F>
where
F: Fn(&D::Value) -> bool,
{
ValueFilteredQueryIterator::new(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
filter,
)
}
pub fn query_values(
&self,
term: &str,
max_distance: usize,
) -> ValueYieldingQueryIterator<D::Node> {
ValueYieldingQueryIterator::new(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
)
}
pub fn query_by_value_set(
&self,
term: &str,
max_distance: usize,
value_set: &HashSet<D::Value>,
) -> ValueSetFilteredQueryIterator<D::Node, D::Value>
where
D::Value: Eq + std::hash::Hash + Clone,
{
ValueSetFilteredQueryIterator::new(
self.dictionary.root(),
term.to_string(),
max_distance,
self.algorithm,
value_set.clone(),
)
}
}