use std::sync::Arc;
use anyhow::Result;
use crate::algorithms::compose::compose_filters::{
AltSequenceComposeFilterBuilder, MatchComposeFilterBuilder, NoMatchComposeFilterBuilder,
NullComposeFilterBuilder, SequenceComposeFilterBuilder, TrivialComposeFilterBuilder,
};
use crate::algorithms::compose::matchers::SortedMatcher;
use crate::algorithms::compose::ComposeFst;
use crate::fst_traits::{AllocableFst, ExpandedFst, MutableFst};
use crate::semirings::Semiring;
#[derive(PartialOrd, PartialEq, Debug, Clone, Copy)]
pub enum ComposeFilterEnum {
AutoFilter,
NullFilter,
TrivialFilter,
SequenceFilter,
AltSequenceFilter,
MatchFilter,
NoMatchFilter,
}
#[derive(PartialOrd, PartialEq, Debug, Clone, Copy)]
pub struct ComposeConfig {
pub compose_filter: ComposeFilterEnum,
pub connect: bool,
}
impl Default for ComposeConfig {
fn default() -> Self {
Self {
compose_filter: ComposeFilterEnum::AutoFilter,
connect: true,
}
}
}
pub fn compose_with_config<
W: Semiring,
F1: ExpandedFst<W>,
F2: ExpandedFst<W>,
F3: MutableFst<W> + AllocableFst<W>,
>(
fst1: Arc<F1>,
fst2: Arc<F2>,
config: ComposeConfig,
) -> Result<F3> {
let mut ofst: F3 = match config.compose_filter {
ComposeFilterEnum::AutoFilter => ComposeFst::new_auto(fst1, fst2)?.compute()?,
ComposeFilterEnum::NullFilter => ComposeFst::<
_,
NullComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::SequenceFilter => ComposeFst::<
_,
SequenceComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::AltSequenceFilter => ComposeFst::<
_,
AltSequenceComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::MatchFilter => ComposeFst::<
_,
MatchComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::NoMatchFilter => ComposeFst::<
_,
NoMatchComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::TrivialFilter => ComposeFst::<
_,
TrivialComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
};
if config.connect {
crate::algorithms::connect(&mut ofst)?;
}
Ok(ofst)
}
pub fn compose<
W: Semiring,
F1: ExpandedFst<W>,
F2: ExpandedFst<W>,
F3: MutableFst<W> + AllocableFst<W>,
>(
fst1: Arc<F1>,
fst2: Arc<F2>,
) -> Result<F3> {
let config = ComposeConfig::default();
compose_with_config(fst1, fst2, config)
}