rustfst_ffi/algorithms/
shortest_path.rs1use anyhow::anyhow;
2
3use crate::fst::CFst;
4use crate::{get, wrap, RUSTFST_FFI_RESULT};
5
6use ffi_convert::*;
7use rustfst::algorithms::{shortest_path, shortest_path_with_config, ShortestPathConfig};
8use rustfst::fst_impls::VectorFst;
9use rustfst::semirings::TropicalWeight;
10
11#[derive(AsRust, CReprOf, CDrop, RawPointerConverter)]
12#[target_type(ShortestPathConfig)]
13pub struct CShortestPathConfig {
14 delta: f32,
15 nshortest: usize,
16 unique: bool,
17}
18
19#[no_mangle]
23pub unsafe extern "C" fn fst_shortest_path_config_new(
24 delta: libc::c_float,
25 nshortest: libc::size_t,
26 unique: bool,
27 ptr: *mut *const CShortestPathConfig,
28) -> RUSTFST_FFI_RESULT {
29 wrap(|| {
30 let config = CShortestPathConfig {
31 delta,
32 nshortest,
33 unique,
34 };
35 unsafe { *ptr = config.into_raw_pointer() };
36 Ok(())
37 })
38}
39
40#[no_mangle]
44pub unsafe extern "C" fn fst_shortest_path(
45 ptr: *const CFst,
46 res_fst: *mut *const CFst,
47) -> RUSTFST_FFI_RESULT {
48 wrap(|| {
49 let fst = get!(CFst, ptr);
50 let vec_fst: &VectorFst<TropicalWeight> = fst
51 .downcast_ref()
52 .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
53 let res: VectorFst<TropicalWeight> = shortest_path(vec_fst)?;
54 unsafe { *res_fst = CFst(Box::new(res)).into_raw_pointer() };
55 Ok(())
56 })
57}
58
59#[no_mangle]
63pub unsafe extern "C" fn fst_shortest_path_with_config(
64 ptr: *const CFst,
65 config: *const CShortestPathConfig,
66 res_fst: *mut *const CFst,
67) -> RUSTFST_FFI_RESULT {
68 wrap(|| {
69 let fst = get!(CFst, ptr);
70 let vec_fst: &VectorFst<TropicalWeight> = fst
71 .downcast_ref()
72 .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
73
74 let config = unsafe {
75 <CShortestPathConfig as ffi_convert::RawBorrow<CShortestPathConfig>>::raw_borrow(
76 config,
77 )?
78 };
79 let res: VectorFst<TropicalWeight> = shortest_path_with_config(vec_fst, config.as_rust()?)?;
80 unsafe { *res_fst = CFst(Box::new(res)).into_raw_pointer() };
81 Ok(())
82 })
83}