rustfst/algorithms/
fst_convert.rs1use crate::fst_traits::{AllocableFst, ExpandedFst, Fst, MutableFst};
2use crate::semirings::Semiring;
3use crate::Trs;
4
5pub fn fst_convert_from_ref<W, F1, F2>(ifst: &F1) -> F2
7where
8 W: Semiring,
9 F1: Fst<W>,
10 F2: MutableFst<W> + AllocableFst<W>,
11{
12 let mut ofst = F2::new();
13
14 ofst.add_states(ifst.states_iter().count());
16
17 if let Some(start) = ifst.start() {
18 unsafe { ofst.set_start_unchecked(start) };
19
20 for data in ifst.fst_iter() {
21 unsafe {
22 ofst.reserve_trs_unchecked(data.state_id, data.num_trs);
23 }
24 for tr in data.trs.trs() {
25 unsafe { ofst.add_tr_unchecked(data.state_id, tr.clone()) };
26 }
27
28 if let Some(final_weight) = data.final_weight {
29 unsafe { ofst.set_final_unchecked(data.state_id, final_weight.clone()) };
30 }
31 }
32 }
33
34 ofst.set_symts_from_fst(ifst);
35 ofst.set_properties_with_mask(ifst.properties(), ifst.properties());
36
37 ofst
38}
39
40pub fn fst_convert<W, F1, F2>(ifst: F1) -> F2
42where
43 W: Semiring,
44 F1: ExpandedFst<W>,
45 F2: MutableFst<W> + AllocableFst<W>,
46{
47 let mut ofst = F2::new();
48 ofst.add_states(ifst.num_states());
49
50 ofst.set_symts_from_fst(&ifst);
51 let iprops = ifst.properties();
52
53 if let Some(start) = ifst.start() {
54 unsafe { ofst.set_start_unchecked(start) };
55
56 for fst_iter_data in ifst.fst_into_iter() {
57 unsafe {
58 ofst.reserve_trs_unchecked(fst_iter_data.state_id, fst_iter_data.num_trs);
59 }
60 for tr in fst_iter_data.trs {
61 unsafe { ofst.add_tr_unchecked(fst_iter_data.state_id, tr) }
62 }
63
64 if let Some(w) = fst_iter_data.final_weight {
65 unsafe { ofst.set_final_unchecked(fst_iter_data.state_id, w) };
66 }
67 }
68 }
69
70 ofst.set_properties_with_mask(iprops, iprops);
71
72 ofst
73}