use fst_traits::{ExpandedFst, MutableFst};
use std::mem::swap;
use Result;
pub fn invert<F: ExpandedFst + MutableFst>(fst: &mut F) -> Result<()> {
let states: Vec<_> = fst.states_iter().collect();
for state_id in states {
for arc in fst.arcs_iter_mut(&state_id)? {
swap(&mut arc.ilabel, &mut arc.olabel);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use counter::Counter;
use fst_traits::PathsIterator;
use test_data::vector_fst::get_vector_fsts_for_tests;
#[test]
fn test_invert_generic() {
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).unwrap();
let paths: Counter<_> = projected_fst.paths_iter().collect();
assert_eq!(
paths, paths_ref,
"Test failing for invert on wFST {:?}",
&data.name
)
}
}
}