rustfst_ffi/algorithms/
project.rs

1use anyhow::{anyhow, Result};
2
3use super::EnumConversionError;
4use crate::fst::CFst;
5use crate::{get_mut, wrap, RUSTFST_FFI_RESULT};
6
7use ffi_convert::*;
8use rustfst::algorithms::{project, ProjectType};
9use rustfst::fst_impls::VectorFst;
10use rustfst::semirings::TropicalWeight;
11
12#[derive(RawPointerConverter)]
13pub struct CProjectType(usize);
14
15impl AsRust<ProjectType> for CProjectType {
16    fn as_rust(&self) -> Result<ProjectType, AsRustError> {
17        match self.0 {
18            0 => Ok(ProjectType::ProjectInput),
19            1 => Ok(ProjectType::ProjectOutput),
20            _ => Err(AsRustError::Other(Box::new(EnumConversionError {}))),
21        }
22    }
23}
24
25impl CDrop for CProjectType {
26    fn do_drop(&mut self) -> Result<(), CDropError> {
27        Ok(())
28    }
29}
30
31impl CReprOf<ProjectType> for CProjectType {
32    fn c_repr_of(value: ProjectType) -> Result<CProjectType, CReprOfError> {
33        let variant = match value {
34            ProjectType::ProjectInput => 0,
35            ProjectType::ProjectOutput => 1,
36        };
37        Ok(CProjectType(variant))
38    }
39}
40
41/// # Safety
42///
43/// The pointers should be valid.
44#[no_mangle]
45pub unsafe extern "C" fn fst_project_type_new(
46    project_type: libc::size_t,
47    ptr: *mut *const CProjectType,
48) -> RUSTFST_FFI_RESULT {
49    wrap(|| {
50        let project_type = CProjectType(project_type);
51        unsafe { *ptr = project_type.into_raw_pointer() };
52        Ok(())
53    })
54}
55
56/// # Safety
57///
58/// The pointers should be valid.
59#[no_mangle]
60pub unsafe extern "C" fn fst_project(
61    ptr: *mut CFst,
62    config: *const CProjectType,
63) -> RUSTFST_FFI_RESULT {
64    wrap(|| {
65        let fst = get_mut!(CFst, ptr);
66        let vec_fst: &mut VectorFst<TropicalWeight> = fst
67            .downcast_mut()
68            .ok_or_else(|| anyhow!("Could not downcast to vector FST"))?;
69
70        let project_type =
71            unsafe { <CProjectType as ffi_convert::RawBorrow<CProjectType>>::raw_borrow(config)? };
72
73        project(vec_fst, project_type.as_rust()?);
74        Ok(())
75    })
76}