rustfst/algorithms/encode/
decode_static.rs1use anyhow::{Context, Result};
2
3use crate::algorithms::{encode::EncodeTable, rm_final_epsilon};
4use crate::algorithms::{FinalTr, MapFinalAction, TrMapper};
5use crate::fst_properties::FstProperties;
6use crate::fst_traits::MutableFst;
7use crate::{Semiring, Tr};
8
9struct DecodeMapper<W: Semiring> {
10 encode_table: EncodeTable<W>,
11}
12
13impl<W: Semiring> DecodeMapper<W> {
14 pub fn new(encode_table: EncodeTable<W>) -> Self {
15 DecodeMapper { encode_table }
16 }
17
18 pub fn encode_weights(&self) -> bool {
19 self.encode_table.0.borrow().encode_type.encode_weights()
20 }
21
22 pub fn encode_labels(&self) -> bool {
23 self.encode_table.0.borrow().encode_type.encode_labels()
24 }
25}
26
27impl<W: Semiring> TrMapper<W> for DecodeMapper<W> {
28 fn tr_map(&self, tr: &mut Tr<W>) -> Result<()> {
29 let tuple = self
30 .encode_table
31 .0
32 .borrow_mut()
33 .decode(tr.ilabel as usize)
34 .ok_or_else(|| format_err!("Can't decode ilabel : {:?}", tr.ilabel))?
35 .clone();
36 tr.ilabel = tuple.ilabel;
37 if self.encode_labels() {
38 tr.olabel = tuple.olabel;
39 }
40 if self.encode_weights() {
41 tr.weight = tuple.weight;
42 }
43 Ok(())
44 }
45
46 fn final_tr_map(&self, _final_tr: &mut FinalTr<W>) -> Result<()> {
47 Ok(())
48 }
49
50 fn final_action(&self) -> MapFinalAction {
51 MapFinalAction::MapNoSuperfinal
52 }
53
54 fn properties(&self, inprops: FstProperties) -> FstProperties {
55 let outprops = inprops;
56 let mut mask = FstProperties::all_properties();
57 if self.encode_labels() {
58 mask &= FstProperties::i_label_invariant_properties()
59 & FstProperties::o_label_invariant_properties();
60 }
61 if self.encode_weights() {
62 mask &= FstProperties::i_label_invariant_properties()
63 & FstProperties::weight_invariant_properties()
64 & FstProperties::rm_super_final_properties()
65 }
66 outprops & mask
67 }
68}
69
70pub fn decode<W, F>(fst: &mut F, encode_table: EncodeTable<W>) -> Result<()>
73where
74 W: Semiring,
75 F: MutableFst<W>,
76{
77 let mut decode_mapper = DecodeMapper::new(encode_table);
78 fst.tr_map(&mut decode_mapper)
79 .with_context(|| format_err!("Error calling TrMap with EncodeMapper."))?;
80 rm_final_epsilon(fst)?;
81 Ok(())
82}