rustfst_ffi/algorithms/
determinize.rs1use anyhow::{anyhow, Result};
2
3use super::EnumConversionError;
4use crate::fst::CFst;
5use crate::{get, wrap, RUSTFST_FFI_RESULT};
6
7use ffi_convert::*;
8use rustfst::algorithms::determinize::{
9 determinize, determinize_with_config, DeterminizeConfig, DeterminizeType,
10};
11use rustfst::fst_impls::VectorFst;
12use rustfst::semirings::TropicalWeight;
13
14#[derive(RawPointerConverter)]
15pub struct CDeterminizeType(usize);
16
17impl AsRust<DeterminizeType> for CDeterminizeType {
18 fn as_rust(&self) -> Result<DeterminizeType, AsRustError> {
19 match self.0 {
20 0 => Ok(DeterminizeType::DeterminizeFunctional),
21 1 => Ok(DeterminizeType::DeterminizeNonFunctional),
22 2 => Ok(DeterminizeType::DeterminizeDisambiguate),
23 _ => Err(AsRustError::Other(Box::new(EnumConversionError {}))),
24 }
25 }
26}
27
28impl CDrop for CDeterminizeType {
29 fn do_drop(&mut self) -> Result<(), CDropError> {
30 Ok(())
31 }
32}
33
34impl CReprOf<DeterminizeType> for CDeterminizeType {
35 fn c_repr_of(value: DeterminizeType) -> Result<CDeterminizeType, CReprOfError> {
36 let variant = match value {
37 DeterminizeType::DeterminizeFunctional => 0,
38 DeterminizeType::DeterminizeNonFunctional => 1,
39 DeterminizeType::DeterminizeDisambiguate => 2,
40 };
41 Ok(CDeterminizeType(variant))
42 }
43}
44
45#[derive(AsRust, CReprOf, CDrop, RawPointerConverter)]
46#[target_type(DeterminizeConfig)]
47pub struct CDeterminizeConfig {
48 delta: f32,
49 det_type: CDeterminizeType,
50}
51
52#[no_mangle]
56pub unsafe extern "C" fn fst_determinize_config_new(
57 delta: libc::c_float,
58 det_type: libc::size_t,
59 config: *mut *const CDeterminizeConfig,
60) -> RUSTFST_FFI_RESULT {
61 wrap(|| {
62 let determinize_config = CDeterminizeConfig {
63 delta,
64 det_type: CDeterminizeType(det_type),
65 };
66 unsafe { *config = determinize_config.into_raw_pointer() };
67 Ok(())
68 })
69}
70
71#[no_mangle]
75pub unsafe extern "C" fn fst_determinize(
76 ptr: *const CFst,
77 det_fst: *mut *const CFst,
78) -> RUSTFST_FFI_RESULT {
79 wrap(|| {
80 let fst = get!(CFst, ptr);
81 let vec_fst: &VectorFst<TropicalWeight> = fst
82 .downcast_ref()
83 .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
84 let fst: VectorFst<TropicalWeight> = determinize(vec_fst)?;
85 let fst_ptr = CFst(Box::new(fst)).into_raw_pointer();
86 unsafe { *det_fst = fst_ptr };
87 Ok(())
88 })
89}
90
91#[no_mangle]
95pub unsafe extern "C" fn fst_determinize_with_config(
96 ptr: *const CFst,
97 config: *const CDeterminizeConfig,
98 det_fst: *mut *const CFst,
99) -> RUSTFST_FFI_RESULT {
100 wrap(|| {
101 let fst = get!(CFst, ptr);
102 let vec_fst: &VectorFst<TropicalWeight> = fst
103 .downcast_ref()
104 .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
105
106 let det_config = unsafe {
107 <CDeterminizeConfig as ffi_convert::RawBorrow<CDeterminizeConfig>>::raw_borrow(config)?
108 };
109 let fst: VectorFst<TropicalWeight> =
110 determinize_with_config(vec_fst, det_config.as_rust()?)?;
111 let fst_ptr = CFst(Box::new(fst)).into_raw_pointer();
112 unsafe { *det_fst = fst_ptr };
113 Ok(())
114 })
115}