use failure::Fallible;
use std::mem::swap;
use crate::algorithms::{ArcMapper, FinalArc, MapFinalAction};
use crate::fst_traits::{ExpandedFst, MutableFst};
use crate::semirings::Semiring;
use crate::Arc;
pub fn invert<F: ExpandedFst + MutableFst>(fst: &mut F) {
let mut mapper = InvertMapper {};
fst.arc_map(&mut mapper).unwrap();
}
struct InvertMapper {}
impl<W: Semiring> ArcMapper<W> for InvertMapper {
fn arc_map(&mut self, arc: &mut Arc<W>) -> Fallible<()> {
swap(&mut arc.ilabel, &mut arc.olabel);
Ok(())
}
fn final_arc_map(&mut self, _final_arc: &mut FinalArc<W>) -> Fallible<()> {
Ok(())
}
fn final_action(&self) -> MapFinalAction {
MapFinalAction::MapNoSuperfinal
}
}
#[cfg(test)]
mod tests {
use super::*;
use counter::Counter;
use failure::Fallible;
use crate::fst_traits::PathsIterator;
use crate::test_data::vector_fst::get_vector_fsts_for_tests;
#[test]
fn test_invert_generic() -> Fallible<()> {
for data in get_vector_fsts_for_tests() {
let fst = &data.fst;
let paths_ref: Counter<_> = fst
.paths_iter()
.map(|mut p| {
swap(&mut p.ilabels, &mut p.olabels);
p
})
.collect();
let mut projected_fst = fst.clone();
invert(&mut projected_fst);
let paths: Counter<_> = projected_fst.paths_iter().collect();
assert_eq!(
paths, paths_ref,
"Test failing for invert on wFST {:?}",
&data.name
)
}
Ok(())
}
}