rustfst_ffi/algorithms/
optimize.rs

1use anyhow::anyhow;
2
3use crate::fst::CFst;
4use crate::{get, get_mut, wrap, RUSTFST_FFI_RESULT};
5
6use ffi_convert::RawPointerConverter;
7use rustfst::algorithms::weight_converters::SimpleWeightConverter;
8use rustfst::algorithms::{optimize, weight_convert};
9use rustfst::fst_impls::VectorFst;
10use rustfst::semirings::LogWeight;
11use rustfst::semirings::TropicalWeight;
12
13/// # Safety
14///
15/// The pointers should be valid.
16#[no_mangle]
17pub unsafe extern "C" fn fst_optimize(ptr: *mut CFst) -> RUSTFST_FFI_RESULT {
18    wrap(|| {
19        let fst = get_mut!(CFst, ptr);
20        let vec_fst: &mut VectorFst<TropicalWeight> = fst
21            .downcast_mut()
22            .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
23        optimize(vec_fst)?;
24        Ok(())
25    })
26}
27
28/// # Safety
29///
30/// The pointers should be valid.
31#[no_mangle]
32pub unsafe extern "C" fn fst_optimize_in_log(ptr: *mut *const CFst) -> RUSTFST_FFI_RESULT {
33    wrap(|| {
34        let fst_ptr = unsafe { *ptr };
35
36        let fst = get!(CFst, fst_ptr);
37        let vec_fst: &VectorFst<TropicalWeight> = fst
38            .downcast_ref()
39            .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
40
41        let mut converter = SimpleWeightConverter {};
42        let mut vec_log_fst: VectorFst<LogWeight> = weight_convert(vec_fst, &mut converter)?;
43        optimize(&mut vec_log_fst)?;
44        let res_fst: VectorFst<TropicalWeight> = weight_convert(&vec_log_fst, &mut converter)?;
45        let res_ptr = CFst(Box::new(res_fst)).into_raw_pointer();
46        unsafe { *ptr = res_ptr };
47        Ok(())
48    })
49}